我从两个不同的工具Array1
和Array2
中提取了两个计算机列表。
现在我需要提取Array1
中但不在Array2
中的内容。
我设法通过这样做获得所有匹配的:
$matchingComp = @()
foreach ($SCCMcomputer in $SCCMcomputers) {
foreach ($eWPTcomputer in $eWPTcomputers) {
if ($SCCMcomputer.Computername -eq $eWPTComputer.Computername) {
$obj = New-Object PSObject
$obj | Add-Member -MemberType NoteProperty -Name "ComputerName" -Value $SCCMcomputer.Computername
$matchingComp +=$obj
}
}
}
$matchingComp | Export-Csv $inEWPT -Delimiter "," -NoTypeInformation
但我仍然需要$SCCMcomputer
但不在$eWPTcomputers
中的那些......
我在其他语言(例如Perl)上找到了SO的解决方案,但没有找到适用于PowerShell的解决方案。
更新
我仍然无法使用以下公式在Excel中获得正确的输出:
输出如下:
意味着有些人在这里,有些则没有。 powershell中的输出就像这样
表示0KB是emtpy。
$SCCMcomputers | Export-Csv $sccmexport -Delimiter "," -NoTypeInformation
$eWPTcomputers | Export-Csv $ewptexport -Delimiter "," -NoTypeInformation
Compare-Object -ReferenceObject $SCCMcomputers -DifferenceObject $eWPTcomputers | ?{$_.sideIndicator -eq "=>"} |select inputobject | Export-Csv $inEWPT -NoTypeInformation
Compare-Object -ReferenceObject $SCCMcomputers -DifferenceObject $eWPTcomputers | ?{$_.sideIndicator -eq "=="} |select inputobject | Export-Csv $inBoth -NoTypeInformation
Compare-Object -ReferenceObject $SCCMcomputers -DifferenceObject $eWPTcomputers | ?{$_.sideIndicator -eq "<="} |select inputobject | Export-Csv $inSCCM -NoTypeInformation
来自SCCMcomptuers / eWPTcomputers的列名(或其名称)是&#34; Computername&#34;
知道我可能做错了吗?两个计算机阵列都是从SQL和哈希表(我认为它被称为)生成的:@{Computername=......}@{Computername....
,就像这样。
更新2
foreach ($t in $sccmComputers) {
$Test1 += $t.computername
}
$Test2 = @()
foreach ($t in $ewptComputers) {
$Test2 += $t.computername
}
删除Hashtable的Header,只是让数组充满了字符串,幻想着......甚至-Property computername
都没有用......:S
答案 0 :(得分:11)
使用compare-object
cmdlet
Compare-Object -ReferenceObject $sccm -DifferenceObject $wpt | ?{$_.sideIndicator -eq "<="} |select inputobject
示例:
$sccm=@(1,2,3)
$wpt=@(2,4)
Compare-Object -ReferenceObject $sccm -DifferenceObject $wpt -IncludeEqual
将输出:
InputObject SideIndicator
2 == 4 => 1 <= 3 <=
这意味着价值&#34; 2&#34;在两个对象上,&#34; 1&#34;和&#34; 3&#34;仅在&#34;左侧&#34; (即参考对象),而&#34; 4&#34;只是在差异对象
答案 1 :(得分:2)
使用compare-object
如下
Compare-Object -ReferenceObject $sccm -DifferenceObject $wpt -passthru
这应该只给你$ sccm中的对象,而不是$ wpt。
<强> CORRECTION:强>
以上代码适用于保证DifferenceObject是ReferenceObject的子集的情况。但是,如果DifferenceObject中还有其他对象存在于ReferenceObject中,则它将失败。上面的代码返回EITHER ReferenceObject或DifferenceObject中存在但在两者中都不存在的任何对象。
要正确返回ReferenceObject中仅在DifferenceObject中不存在的对象,需要以下代码:
Compare-Object -ReferenceObject $sccm -DifferenceObject $wpt |
Where-Object { $_.SideIndicator -eq '<=' } |
ForEach-Object { Write-Output $_.InputObject }
where-object
子句确保只有ReferenceObject中存在的对象才会传递给管道。
foreach-object
子句强制输出回一个简单的数组(参考:Converting Custom Object arrays to String arrays in Powershell - 谢谢Keith)
答案 2 :(得分:1)
您可以使用-contains
和-notcontains
$A1 ="asd","zxc","qwe",'a'
$A2 = "asd","zxc","bqwe",'b'
$A1,$A2 |
%{
$_|
%{
If ($A1 -contains $_ -and $A2 -notcontains $_) {$_}
}
}
答案 3 :(得分:1)
Compare-Object方法确实是最好的。还没有解决的问题是Excel文件的清晰输出。
Compare-Object $sccm $ewpt | ?{ $_.SideIndicator -eq '<=' | Export-Csv sccm-only.csv -NoTypeInformation
将生成两列。一个用&#34; InputObject&#34;和你的计算机名称,另一栏用&#34; SideIndicator&#34;和一堆行&#34;&lt; =&#34;。
简单的解决方法是只选择您想要的列:
Compare-Object $sccm $ewpt | ?{ $_.SideIndicator -eq '<=' | Select-Object InputObject | Export-Csv sccm-only.csv -NoTypeInformation
这将为您提供一个标有&#34; InputObject&#34;的列。和你的电脑名称。
如果要更改列标签,请使用其他线程Windows Powershell Rename Column Heading CSV file:
中的方法Compare-Object $sccm $ewpt | ?{ $_.SideIndicator -eq '<=' | Select-Object @{ expression={$_.InputObject}; label='ComputerName' } | Export-Csv sccm-only.csv -NoTypeInformation
此外,只需更改SideIndicator比较以获取两个系统中的计算机,或仅在eWPT中:
# Only in eWPT
Compare-Object $sccm $ewpt | ?{ $_.SideIndicator -eq '=>' | Select-Object @{ expression={$_.InputObject}; label='ComputerName' } | Export-Csv sccm-only.csv -NoTypeInformation
# In both SCCM and eWPT
Compare-Object $sccm $ewpt | ?{ $_.SideIndicator -eq '==' | Select-Object @{ expression={$_.InputObject}; label='ComputerName' } | Export-Csv sccm-only.csv -NoTypeInformation
答案 4 :(得分:0)
$sccm=@(1,2,2,3)
$wpt=@(2,4)
Compare-Object -ReferenceObject $sccm -DifferenceObject $wpt |
Where-Object { $_.SideIndicator -eq '<=' } |
ForEach-Object { Write-Output $_.InputObject }
这将返回1,2,3,此方法不正确