1

我正在对一个位置(原始文件夹)中的所有文件进行哈希处理,并将哈希值写入变量,然后对另一个位置(目标文件夹)中的所有文件执行相同操作:

$origin = Get-ChildItem .\Test1 | Get-FileHash | Format-Table -Property Hash -HideTableHeaders
$destination = Get-ChildItem .\Test2 | Get-FileHash | Format-Table -Property Hash -HideTableHeaders

然后我将它们与 Compare-Object 进行比较,如下所示:

Compare-Object $origin $destination

现在在我的测试中我故意有偏差,所以当上面的代码没有返回差异时,我知道我有问题。

然后我发现如果我执行以下操作,则哈希值不存在:

PS>写主机 "$origin"
Microsoft.PowerShell.Commands.Internal.Format.FormatStartData Microsoft.PowerShell.Commands.Internal.Format.GroupStartData Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData Microsoft.PowerShell.Commands。 Internal.Format.FormatEntryData Microsoft.PowerShell.Commands.Internal.Format.GroupEndData Microsoft.PowerShell.Commands.Internal.Format.FormatEndData

但是,如果我只是键入以下内容并按 Enter,则存在哈希值(如我所愿):

PS> $原点

6B86B273FF34FCE19D6B804EFF5A3F5747ADA4EAA22F1D49C01E52DDB7875B4B
D4735E3A265E16EEE03F59718B9B5D03019C07D8B6C51F90DA3A666EEC13AB35
4E07408562BEDB8B60CE05C1DECFE3AD16B72230967DE01F640B7E4729B49FCE

我假设当我使用Compare-Object时,我的变量没有像我预期的那样呈现散列值。

有谁知道发生了什么或有什么建议?这用于确保文件从原始位置移动到目标位置(这是我正在处理的脚本中的一项检查)。我保留这个纯粹的 PowerShell,这意味着 noxcopyrobocopy.

4

1 回答 1

3

重新使用Format-Table来创建输入集合Compare-Object

只使用Format-*cmdlet 进行显示格式化;如果必须以编程方式处理数据,切勿使用它们。

Format-*cmdlet 输出格式化指令,而不是数据- 请参阅此答案

所以:

  • 省略Format-Table输入集合定义命令中的调用:
$origin=Get-ChildItem .\Test1 | Get-FileHash
$destination=Get-ChildItem .\Test2 | Get-FileHash
  • 然后传递属性的名称来比较对象Compare-Object
Compare-Object $origin $destination -Property Path, Hash

请注意,需要同时按路径和哈希进行比较,以确保仅比较同名文件。

顺便说一句:如果您没有指定-Property,则默认情况下将通过它们的.ToString()值来比较对象 - 并且由于Microsoft.PowerShell.Commands.FileHashInfo实例输出Get-FileHash仅字符串化为该类型名称(无论它们的特定属性值如何),因此不会发现任何差异.


至于$originWrite-Host $orgin

  • 只是执行$origin就像执行一样隐含Write-Output $origin- 它写入成功输出流(请参阅about_Redirection),默认情况下会发送到控制台。

  • Write-Host相比之下,与不同的目的Write-Output

    • 直接写入控制台[1]绕过PowerShell 的成功输出流,从而绕过其通常的格式。它的主要目的是向显示器写入状态消息、交互式提示消息……而不是输出数据

    • Write-Host 本身应用输出格式,但只能通过简单的.ToString()字符串化,这通常会产生无用的(仅类型名称)表示,就像您的情况一样。

有关和之间差异的更多信息,请参阅此答案Write-OutputWrite-Host


[1] 从技术上讲,从 PowerShell 版本 5 开始,输出通过信息输出流(数字)Write-Host到达控制台,但其主要目的仍然是写入显示器而不是输出数据6

于 2019-11-12T20:26:50.397 回答