Powershell - 比较两个数组会返回错误的结果

时间:2012-09-17 19:22:37

标签: powershell powershell-v2.0

我希望有人能够帮助解决我在比较阵列时遇到的问题。

这是一些背景知识。我有一个powershell脚本,它生成一个域控制器列表,检查它们是否在线,然后将数据写入csv文件。这很好。

我想每周运行一次并在添加或删除任何域控制器时发送警报。

我有另一个脚本将先前生成的CSV导入数组,然后生成新的域控制器列表并将该列表发送到新数组。我试图使用compare-object比较两者,并导出一个带有差异列表的新CSV。

但是,我正在通过手动修改旧的CSV来测试这个,我发现无论我从上一个列表中删除哪个域控制器,或者我添加新域名,它总是报告更改是列表中的最后一个域控制器。

例如,这是我的CSV文件的样子:

"DC_Name","Ping_Response"
"dc1.testcompany.com","online"
"dc2.testcompany.com","online"
"dc3.testcompany.com","online"
"dc4.testcompany.com","online"

如果我通过删除“dc3.testcompany.com”,“online”并再次运行脚本来测试它,它知道列表已更改,但它报告新条目是“dc4.testcompany.com”, “在线”而不是“dc3.testcompany.com”,“在线”。

同样,如果我将旧的csv修改为如下所示:

"DC_Name","Ping_Response"
"dc1.testcompany.com","online"
"dc2.testcompany.com","online"
"dc5.testcompany.com","online"
"dc3.testcompany.com","online"
"dc4.testcompany.com","online"

它会报告与新列表不同的是“dc4.testcompany.com”,“在线”,而不是我在中间添加的那个。

我的比较一定是做错了。这是我正在使用的脚本的相关部分:

$newDCArray = @(Import-CSV DC_List.csv)

$oldDCArray = @(Import-CSV Last_DC_List.csv)

$diff = Compare-Object $oldDCArray $newDCArray

if($diff -eq $null)
    {
    Write-Host "No changes to DCs"
    }
else    
    {
    Write-Host "There have been changes to DCs"
    $diff| Export-CSV DC_Change_List.csv -notypeinformation
    Send-MailMessage –From "xxxx@xxxxxxxx.com" –To "xxxx@xxxxxxxx.com" –Subject "Alert - Domain Controllers Added or Removed" –Body "DC Report Attached" –SmtpServer "smtp.xxxxxxxxxxx.net" -Attachments "DC_Change_List.csv"
    }

如果有人有任何想法,请告诉我!

谢谢! 约翰

2 个答案:

答案 0 :(得分:4)

Import-Csv返回的对象不是您应该与之进行比较的“真实”对象。它们是动态生成的自定义对象。您会注意到,如果您对$newDCArray[0] -eq $oldDCArray[0]进行了明确的检查,它将返回$false。由于没有适当的管道来检查相等性,Compare-Object没有希望正常工作。

但是没关系。 Compare-Object有一个-Property参数,可让您查看给定对象的一个​​或多个特定属性。属性真实对象(字符串),因此比较有效。在您的情况下,您对2个属性感兴趣 - DC_NamePing_Response,因为您想知道服务器是新的/已删除,以及已知服务器是否已脱机。

这应该适合你:

Compare-Object $oldDCArray $newDCArray -Property 'DC_Name','Ping_Response'

另外,请确保-SyncWindow足够大,以便比较准确。或者有时在比较之前简单地对数组进行排序是最容易的,因此您不必担心这一点。

答案 1 :(得分:0)

以下是接受答案的一个版本,它自动确定属性:

$newDCArray = Import-CSV DC_List.csv
$oldDCArray = Import-CSV Last_DC_List.csv

$propNew = ($newDCArray | Get-Member | ?{$_.MemberType -eq "NoteProperty" | Select -expand Name})
$propOld = ($oldDCArray | Get-Member | ?{$_.MemberType -eq "NoteProperty" | Select -expand Name})
$prop = ($propNew + $propOld) | Get-Unique

$diff = Compare-Object $oldDCArray $newDCArray -Property $prop

请注意,执行不同联合的Get-Unique内容仅在csv-File的列不同时才相关。否则,您可以使用其中一个对象的属性。