将文件夹与哈希文件进行比较

Compare folder to a hash file

有很多关于比较两个文件夹的哈希值完整性的问题和答案,例如 假设我有一个复制到备份介质(外部驱动器、闪存、光盘)的文件夹,并且想删除原来的以保存space。

将原始文件夹哈希值(删除前)保存在文本文件中并稍后根据该文件检查备份完整性的最佳方法是什么。

请注意,如果您先删除原件,然后发现备份缺乏完整性,可以说,您所知道的只是那个 出了点问题;未损坏的数据将消失。


您可以创建一个包含 2 列的 CSV 文件,RelativePath(相对于输入目录的完整文件路径)和 Hash,并将其保存到包含 [=32= 的 CSV 文件中]:

$inputDir = 'C:\path\to\dir' # Note: specify a *full* path.
$prefixLen = $inputDir.Length + 1

Get-ChildItem -File -Recurse -LiteralPath $inputDir |
  Get-FileHash |
    Select-Object @{ 
                    Name='RelativePath'
                    Expression={ $_.Path.Substring($prefixLen) } 
                  }, 
                  Hash |
    Export-Csv originalHashes.csv -NoTypeInformation -Encoding utf8

注意:在 PowerShell (Core) 7+ 中,不需要 -NoTypeInformation-Encoding utf8,但请注意文件将有 no UTF-8 BOM;如果需要,请使用 -Encoding utf8bom;相反,在 Windows PowerShell 中,您 总是 得到 BOM。

注:

  • Microsoft.PowerShell.Commands.FileHashInfo instances output by Get-FileHash 还有一个 .Algorithm 属性 命名所使用的散列算法('SHA256' 默认情况下,或通过-Algorithm 参数).
    如果您希望包含此 属性(其值对于所有 CSV 行都是相同的),您只需将 Algorithm 添加到上面传递给 Select-Object 的属性数组中。

  • 注意 hashtable (@{ ... }) passed as the second property argument to Select-Object serves as a calculated property 如何从每个 .Path 属性 值(包含 full 路径).

您稍后可以将相同的命令应用于 backup 目录树,保存到 backupHashes.csv,并将两个 CSV 文件与 Compare-Object:

Compare-Object (Import-Csv -LiteralPath originalHashes.csv) `
               (Import-Csv -LiteralPath backupHashes.csv) `
               -Property RelativePath, Hash

注意:在操作中没有严格需要涉及 files - 一个或两个输出集合可以在内存中捕获并可以直接用于比较 - 只需省略Export-Csv调用上面的命令并保存到一个变量($originalHashes = Get-ChildItem ...)