Compare-Object:PassThru参数改变输入变量

时间:2017-07-25 21:45:20

标签: powershell

使用代码段轻松解释此问题...

Clear-Host

$refObj = New-Object System.Object
$refObj | Add-Member -MemberType NoteProperty -Name ObjectMember1 -Value 123

$diffObj = New-Object System.Object
$diffObj | Add-Member -MemberType NoteProperty -Name ObjectMember1 -Value 456


Write-Output 'Before 1st comparison...'
$refObj | Get-Member | ? { $_.MemberType  -eq 'NoteProperty' } | Select *


$x = Compare-Object -ReferenceObject $refObj -DifferenceObject $diffObj -IncludeEqual

Write-Output 'After 1st comparison...'
$refObj | Get-Member | ? { $_.MemberType  -eq 'NoteProperty' } | Select *


$y = Compare-Object -ReferenceObject $refObj -DifferenceObject $diffObj -PassThru -IncludeEqual

Write-Output 'After 2nd comparison...'
$refObj | Get-Member | ? { $_.MemberType  -eq 'NoteProperty' } | Select *

...和结果(在PS版本3和5中看起来是相同的,没有经过其他任何测试)......

Query results

我努力理解的是,为什么包含-PassThru参数会改变其中一个输入变量,添加一个额外的参数。

除了努力理解为什么会这样,我还想避免它。有没有一种方法可以在不改变输入变量的情况下为Compare-Object cmdlet指定输出变量?

提前致谢。

编辑:现在我很清楚这个问题不够清楚。为了使这更直接....

$y = Compare-Object -ReferenceObject $refObj -DifferenceObject $diffObj -PassThru -IncludeEqual

有了上述内容,我如何停止将SideIndicator添加到$ refObj,并将其添加到$ y?对于Compare-Object来说,它似乎不是一个-OutVariable选项,还有另外一种方法吗?

编辑2: 事实证明,Compare-Object有一个-OutVariable选项,但它似乎不起作用......

Compare-Object -ReferenceObject $refObj -DifferenceObject $diffObj -IncludeEqual -PassThru -OutVariable $objComparisonResults

我希望$ objComparisonResults中有数据,但此变量中没有保存数据。

2 个答案:

答案 0 :(得分:1)

Compare-Object始终添加SideIndicator NoteProperty。看看产生的对象。 PowerShell生成对象,而不是要解析的平面文本。使用-PassThru只会使它出现在控制台输出中。

Clear-Host
$logfile = 'C:\src\t\pt.txt'
if (Test-Path -Path $logfile) { Remove-Item -Path $logfile }

$refObj = New-Object System.Object
$refObj | Add-Member -MemberType NoteProperty -Name ObjectMember1 -Value 123

$diffObj = New-Object System.Object
$diffObj | Add-Member -MemberType NoteProperty -Name ObjectMember1 -Value 456


'Before 1st comparison...' | Out-File -FilePath $logfile -Append -Encoding Ascii

$refObj | Get-Member | ? { $_.MemberType  -eq 'NoteProperty' } | Select * | gm |
    Out-File -FilePath $logfile -Append -Encoding Ascii


$x = Compare-Object -ReferenceObject $refObj -DifferenceObject $diffObj -IncludeEqual | gm |
    Out-File -FilePath $logfile -Append -Encoding Ascii

'After 1st comparison...' | Out-File -FilePath $logfile -Append -Encoding Ascii

$refObj | Get-Member | ? { $_.MemberType  -eq 'NoteProperty' } | Select * | gm |
    Out-File -FilePath $logfile -Append -Encoding Ascii


$y = Compare-Object -ReferenceObject $refObj -DifferenceObject $diffObj -PassThru -IncludeEqual | gm |
    Out-File -FilePath $logfile -Append -Encoding Ascii

'After 2nd comparison...' | Out-File -FilePath $logfile -Append -Encoding Ascii

$refObj | Get-Member | ? { $_.MemberType  -eq 'NoteProperty' } | Select * | gm |
    Out-File -FilePath $logfile -Append -Encoding Ascii

答案 1 :(得分:0)

找到解决方案。而不是试图以这种方式保存Compare-Object导致变量......

$y = Compare-Object -ReferenceObject $refObj -DifferenceObject $diffObj -PassThru -IncludeEqual

...可以通过这种方式保存结果...

$y = (Compare-Object -ReferenceObject $file1 -DifferenceObject $file2 -Property $properties1 -IncludeEqual)

第二种方式,输出保存在$ y中,并且当跳过-PassThru时,我们应该避免将更改保存回输入变量。

作为进一步的改进,可以使用Tee-Object将输出存储在变量中,这也允许我们控制比较对象输出是否自动显示在屏幕上(以下命令中的Out-Null意味着这是输出被抑制):

(Compare-Object -ReferenceObject $refObj -DifferenceObject $diffObj -IncludeEqual) | Tee-Object -Variable y | Out-Null