[英]“$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,这意味着没有xcopy
或robocopy
。
Re use of Format-Table
to create the input collections for Compare-Object
:重新使用Format-Table
为Compare-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:所以:
Format-Table
calls from your input-collection definition commands:从您的输入集合定义命令中省略Format-Table
调用:$origin=Get-ChildItem .\Test1 | Get-FileHash
$destination=Get-ChildItem .\Test2 | Get-FileHash
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
:至于$origin
与Write-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-Output
和Write-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.