简体   繁体   English

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

[英]“$xyz” and “Write-Host ”$xyz“” giving different output

I am hashing all the files in one location, an origin folder, and writing the hashes to a variable and then doing the same to all the files in another location, a destination folder:我正在对一个位置(原始文件夹)中的所有文件进行哈希处理,并将哈希值写入变量,然后对另一个位置(目标文件夹)中的所有文件执行相同操作:

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

Then I am comparing them with Compare-Object like so:然后我将它们与 Compare-Object 进行比较,如下所示:

Compare-Object $origin $destination

Now in my test I purposefully have deviations, so when the above code returned no differences I knew I had a problem.现在在我的测试中我故意有偏差,所以当上面的代码没有返回差异时,我知道我有问题。

Then I found out that if I do the following, that the hash values arn't there:然后我发现如果我执行以下操作,则 hash 值不存在:

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

However, if I just type the following and press enter, then the hash values are present (like I want):但是,如果我只是键入以下内容并按 Enter,则 hash 值存在(如我所愿):

PS> $origin

6B86B273FF34FCE19D6B804EFF5A3F5747ADA4EAA22F1D49C01E52DDB7875B4B
D4735E3A265E16EEE03F59718B9B5D03019C07D8B6C51F90DA3A666EEC13AB35
4E07408562BEDB8B60CE05C1DECFE3AD16B72230967DE01F640B7E4729B49FCE

I am assuming when I use Compare-Object , that my variables are not presenting the hash values like I expected.我假设当我使用Compare-Object时,我的变量没有像我预期的那样呈现 hash 值。

Does anyone know what is going on or have any recommendations?有谁知道发生了什么或有什么建议? This is being used to ensure files are moved from an origin location to a destination location (this is one check in a script I'm working on).这用于确保文件从原始位置移动到目标位置(这是我正在处理的脚本中的一项检查)。 I am keeping this purely PowerShell, which means no xcopy or robocopy .我保留这个纯粹的 PowerShell,这意味着没有xcopyrobocopy

Re use of Format-Table to create the input collections for Compare-Object :重新使用Format-TableCompare-Object创建输入 collections :

Only ever use Format-* cmdlets for display formatting ;仅使用Format-* cmdlet 进行显示格式化 never use them if data must be programmatically processed .如果必须以编程方式处理数据,切勿使用它们

Format-* cmdlets output formatting instructions , not data - see this answer . Format-* cmdlet output格式化指令,而不是数据- 请参阅此答案

Therefore:所以:

  • Omit the Format-Table calls from your input-collection definition commands:从您的输入集合定义命令中省略Format-Table调用:
$origin=Get-ChildItem .\Test1 | Get-FileHash
$destination=Get-ChildItem .\Test2 | Get-FileHash
  • Then pass the names of the properties to compare the objects by to Compare-Object :然后将要比较对象的属性名称传递给Compare-Object
Compare-Object $origin $destination -Property Path, Hash

Note the need to compare by both path and hash, to make sure that only files of the same name are compared.请注意,需要同时按路径和 hash 进行比较,以确保仅比较同名文件。

As an aside: If you didn't specify -Property , the objects would by default be compared by their .ToString() value - and since the Microsoft.PowerShell.Commands.FileHashInfo instances output by Get-FileHash only ever stringify to that very type name (irrespective of their specific property values), no differences would be found.顺便说一句:如果您没有指定-Property ,则默认情况下对象将通过它们的.ToString()值进行比较-并且由于Microsoft.PowerShell.Commands.FileHashInfo实例 output 由Get-FileHash仅字符串化为类型名称(无论它们的具体属性值如何),不会发现任何差异。


As for $origin vs. Write-Host $orgin :至于$originWrite-Host $orgin

  • Just executing $origin is implicitly like executing Write-Output $origin - it writes to the success output stream (see about_Redirection ), which by default goes to the console.仅仅执行$origin就像执行Write-Output $origin一样隐含 - 它写入成功 output stream (参见about_Redirection ),默认情况下会发送到控制台。

  • Write-Host , by contrast, serves a different purpose than Write-Output :相比之下, Write-Host用途Write-Output不同

    • It writes directly to the console [1] , bypassing PowerShell's success output stream and thereby also its usual formatting.直接写入控制台[1]绕过了 PowerShell 的成功 output stream 以及它通常的格式。 Its primary purpose is to write status messages, interactive prompt messages, ... to the display - as opposed to outputting data .它的主要目的是向显示器写入状态消息、交互式提示消息……而不是输出数据

    • Write-Host itself applies output formatting , but only by simple .ToString() stringification , which often yields unhelpful (type name-only) representations, as in your case. Write-Host本身应用 output 格式,但只能通过简单的.ToString()字符串化,这通常会产生无用的(仅类型名称)表示,就像您的情况一样。

See this answer for more information about the differences between Write-Output and Write-Host .有关Write-OutputWrite-Host之间差异的更多信息,请参阅此答案


[1] Technically, since PowerShell version 5, Write-Host output reaches the console via the information output stream (number 6 ), but its primary purpose is still to write to the display as opposed to outputting data . [1] Technically, since PowerShell version 5, Write-Host output reaches the console via the information output stream (number 6 ), but its primary purpose is still to write to the display as opposed to outputting data .

I tried the following code我尝试了以下代码

$dest = Get-ChildItem -Path .\Desktop\sample.pdf | Get-FileHash
$source = Get-ChildItem -Path .\Desktop\sample2.pdf | Get-FileHash

This does not give me any output.这并没有给我任何 output。

Compare-Object -ReferenceObject $source -DifferenceObject $dest

However, I receive a comparison when I specify .Hash property of the variables.但是,当我指定变量的.Hash属性时,我会收到一个比较。

Compare-Object -ReferenceObject $source.Hash -DifferenceObject $dest.Hash
InputObject                 SideIndicator
-----------                 -------------
(Some hash)                 <=  
(Some hash)                 =>

The $source variable otherwise has two key-value pairs.否则$source变量有两个键值对。 I assume the Compare-Object command does not compare the variables down to the bits but rather the over-arching type.我假设Compare-Object命令不会将变量与位进行比较,而是与总体类型进行比较。

Algorithm               Hash
---------               ----
SHA256                  (Some Hash)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM