“ $ xyz”和“ Write-Host” $ xyz“”给出不同的输出

时间:2019-11-12 20:05:55

标签: powershell compareobject write-host get-filehash

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

$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> Write-Host "$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> $origin

6B86B273FF34FCE19D6B804EFF5A3F5747ADA4EAA22F1D49C01E52DDB7875B4B
D4735E3A265E16EEE03F59718B9B5D03019C07D8B6C51F90DA3A666EEC13AB35
4E07408562BEDB8B60CE05C1DECFE3AD16B72230967DE01F640B7E4729B49FCE

我假设当我使用Compare-Object时,我的变量没有像我期望的那样显示哈希值。

有人知道发生了什么或有任何建议吗?这用于确保文件从原始位置移动到目标位置(这是我正在处理的脚本中的一项检查)。我仅使用此PowerShell,这意味着没有xcopyrobocopy

1 个答案:

答案 0 :(得分:3)

重新使用Format-TableCompare-Object创建输入集合:

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

Format-* cmdlet输出格式化说明,而不是数据-请参见this answer

因此:

  • 省略输入集合定义命令中的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一样,它会写入成功输出流 (请参阅{{3} }),默认情况下, 进入控制台。

    • 通过PowerShell的丰富about_Redirection 自动格式化进入控制台的成功输出
  • 相比之下,
  • Write-Host 具有不同于Write-Output 目的

    • 它直接将写入控制台 [1] 绕过 PowerShell的成功输出流,从而也将其格式化。 其主要目的是将状态消息,交互式提示消息...写到显示器上-与输出数据相反。

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

有关Write-OutputWrite-Host之间的区别的更多信息,请参见output-formatting system


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