如何在 PowerShell 中检查哪些文件已损坏

如何在 PowerShell 中检查哪些文件已损坏

我经常运行 chkdsk /f X:(此处的 X 代表实际驱动器号)来检查并修复文件系统错误,但它不会报告哪些文件已损坏。

我在 Windows 10 20H2 x64 上使用 PSCore7.1,我想通过比较文件的哈希值和时间戳与该路径的记录哈希值和时间戳来检查哪些文件已损坏,如果哈希值已更改而时间戳未更改,则文件已损坏。

PowerShell 具有内置函数来获取哈希码,但它不是 SHA-256,我可以使用

Get-ChildItem -Path $path -Force -File -Recurse

要获取文件,.Fullname 获取文件的完整路径,.LastWriteTime 获取时间戳,但这里我谈论的是整个磁盘,所以我希望它尽可能快。

但我不知道如何获取 SHA-256,尽管这并不难。

然后我的想法是创建一个具有三个noteproperties的[PSCustomObject]:Fullname,LastWriteTime和SHA-256,我可以这样做,然后将其直接导出到数据库文件(附加),不幸的是目前我只能设法导出到txt文件,并且查询txt文件会很困难。

最后,如果数据库不存在,则创建它并退出,否则如果数据库存在,则获取数据库的内容,在控制台中创建一个新的数据库并查找损坏的文件。

我可以使用 [System.IO.File]::Exists() 来检查文件是否存在,使用 Convertfrom-String 将 txt 转换为 pscustomobject 数组,尽管它有缺陷,或者使用 for 循环通过索引循环遍历文件,在每次迭代中通过正则表达式匹配获取值,然后创建一个 PSCustomObject 并使用 += 添加到数组中,尽管这可能很慢。

查找损坏文件的最后一步是:

for ($i=0;$i -lt $NewDB.count;$i++) {
    $Database | Where-Object{$_.Fullname -eq $NewDB[$i].Fullname -and $_.LastWriteTime -eq $NewDB[$i].LastWriteTime -and $_.SHA256 -ne $NewDB[$i].SHA256}
}

我并不笨,只是缺乏经验,目前这个脚本需要一些我无法做到的事情:

1、尽快获取驱动器的所有文件

2、获取文件的 SHA-256

3、导出和导入数据

请帮我完成脚本!任何帮助我都会很感激,我会非常感激,答案也可能帮助很多人,我提前说声谢谢。

更新:现在我正在寻找将数据导出为 csv 格式的方法,我是否只需使用 Out-File *.csv?它会自动格式化数据吗?我如何控制格式?以及如何将 csv 直接转换为 PSCustomObject 数组?

编辑:修复了 where 行中缺少的索引。重新编辑:完成 for 循环和 where-object 过程以使其真正发挥作用,以防有人怀疑我的能力或其他人看到此内容却不知道如何操作。

答案1

获取文件的哈希值,即使是 SHA 级别也是很常见的事,可以在 PowerShell 中本地完成,无需第三方软件。请务必先查看帮助文件的完整详细信息。

至于这个……

我经常运行 chkdsk /f X:(此处的 X 代表实际驱动器号)来检查并修复文件系统错误,但它不会报告哪些文件已损坏。

…因为那不是该工具的用途。它的作用正如文档所述。

https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/chkdsk

至于这个……

...我想通过将文件的哈希值和时间戳与该路径的记录哈希值和时间戳进行比较来检查哪些文件已损坏,如果哈希值已更改而时间戳未更改,则文件已损坏。

… 您的 PowerShell 版本与此用例无关。文件哈希更改并不一定意味着损坏。这意味着文件中的内容已更改。正常情况下,损坏的文件无法访问,因为它已损坏。

至于……

…PowerShell 具有内置函数来获取哈希码,但它不是 SHA-256…

…不正确,这是在帮助文件中定义的。

至于…

Get-ChildItem -Path $path -Force -File -Recurse

... 这并不重要,因为性能由文件目标数量、驱动器大小、驱动器性能、CPU 性能、内存、影响操作状态的其他进程(AV 等)等控制。顺便说一句,执行这个哈希检查会使它变得更慢。

这意味着你要把它分成几部分,PowerShell 职位PowerShell 工作流并行处理以获得更好的性能。

至于…

但我不知道如何获取 SHA-256……

...Windows 文件系统的 DPAPI 默认为 SHA-256,除非程序员、数据所有者使用 DPAPI 另行定义。

但是,如果你确实想看到它,那么内置的 cmdletGet-FileHash 允许您这样做。它在帮助文件中定义。

# Get specifics for a module, cmdlet, or function
(Get-Command -Name Get-FileHash).Parameters
(Get-Command -Name Get-FileHash).Parameters.Keys
Get-help -Name Get-FileHash -Examples
# Results
<#
Get-FileHash $pshome\powershell.exe | Format-List
Get-FileHash C:\Users\Andris\Downloads\Contoso8_1_ENT.iso -Algorithm SHA384 | Format-List
#>
Get-help -Name Get-FileHash -Full
Get-help -Name Get-FileHash -Online



Get-ChildItem -Path D:\Temp | 
ForEach{Get-FileHash -Path $PSItem.FullName}
# Results
<#
Algorithm       Hash                   Path                                                                                                      
---------       ----                    ----                                                                                                      
SHA256          84F07167E6A9E3...      D:\Temp\(MSINFO32) command-line...                                                        
SHA256          A3CB4415D3FAAA...      D:\Temp\23694d1213305764-revisi... 
...
#>

也可以看看:

Carbon Black Defense:如何在 Windows 和 Mac 上获取文件的 SHA 256 哈希值

Windows 的步骤 - Powershell 打开 Windows Powershell 输入以下命令(将 <path/to/file> 替换为您要从中获取哈希的文件或应用程序的绝对路径):

至于...

然后我的想法是创建一个具有三个 noteproperties 的 [PSCustomObject]:Fullname、LastWriteTime 和 SHA-256,...

... 这:

Get-ChildItem -Path D:\Temp | 
ForEach{
    [PSCustomObject] @{
        FileName      = $PSItem.FullName
        LastWriteTIme = $PSItem.LastWriteTime
        ShaVersion    = (Get-FileHash -Path $PSItem.FullName).Algorithm 
        Hash          = (Get-FileHash -Path $PSItem.FullName).Hash 
    }
}
# Results
<#
FileName                        LastWriteTIme      ShaVersion Hash                                             
--------                        -------------      ---------- ----                                             
D:\Temp\(MSINFO32) command...   06-Aug-16 18:25:22 SHA256     84F07167E6A9E3...
D:\Temp\23694d1213305764-r...   06-Feb-20 14:02:47 SHA256     A3CB4415D3FAAA...
D:\Temp\5 Free Software Yo...   29-Dec-19 21:50:56 SHA256     3427AD8DC44986...
#>

根据您的评论“如何导出和导入 csv”进行更新

Get-ChildItem -Path D:\Temp | 
ForEach{
    [PSCustomObject] @{
        FileName      = $PSItem.FullName
        LastWriteTIme = $PSItem.LastWriteTime
        ShaVersion    = (Get-FileHash -Path $PSItem.FullName).Algorithm 
        Hash          = (Get-FileHash -Path $PSItem.FullName).Hash 
    } | Export-Csv -Path 'D:\Temp\FileMoniotReport.csv' -NoTypeInformation -Append
}
Import-Csv -Path 'D:\Temp\FileMoniotReport.csv'

相关内容