好,最容易做到這一點的方法是使用Compare-Object
,並與Select
一個小魔術。
我打算假設CSV中的ApplicationName
列是與您的Windows服務列表中的Name
屬性匹配的字符串列表。因此,讓我們從導入該CSV開始,並將ApplicationName
的屬性名稱更改爲Name
,以便它與Windows服務對象上的相關屬性匹配。
$masterList = Import-Csv $csvLocation | Select @{l='Name';e={$_.ApplicationName}}
然後我們只需使用Compare-Object
,看看有什麼在兩個列表:
Compare-Object (Get-Service) -DifferenceObject $masterList -Property Name -IncludeEqual
如果你想解析的-IncludeEqual
和-ExcludeDifferent
參數,你可以它總是管到Where
條款,或使用組合:
$masterList = Import-Csv $csvLocation | Select @{l='Name';e={$_.ApplicationName}}
$myServices = Get-Service
$foundServices = Compare-Object $myServices -DifferenceObject $masterList -Property Name -IncludeEqual -ExcludeDifferent
$servicesNotInMaster = Compare-Object $myServices -DifferenceObject $masterList -Property Name | Where {$_.SideIndicator -eq '<='}
$servicesNotFoundLocally = Compare-Object $myServices -DifferenceObject $masterList -Property Name | Where {$_.SideIndicator -eq '=>'}
或者使用Switch
cmdlet來做到這一切一氣呵成:
$masterList = Import-Csv $csvLocation | Select @{l='Name';e={$_.ApplicationName}}
$myServices = Get-Service
Switch(Compare-Object $myServices -dif $masterList -prop Name -includeequal -PassThru){
{$_.SideIndicator -eq '<='} {[array]$servicesNotInMaster += $_}
{$_.SideIndicator -eq '=>'} {[array]$servicesNotFoundLocally += $_}
{$_.SideIndicator -eq '=='} {[array]$foundServices += $_}
}
編輯:好的,從您的添加更新到OP。看起來你可以簡單地使用Where
子句而不是一遍又一遍地獲得服務。
$services = Get-Service -ComputerName $serverName | Where{$_.Name -like 'ops*' -or $_.Name -like 'Centinel*'} | Select -Expand Name
然後您導入CSV,並再次使用Select -Expand
來獲得屬性的值,而不是通過其循環像你之前。
$masterList = Import-Csv $csvLocation | Select -Expand ApplicationName
現在你只需要串的兩列,所以實際上變得比比較對象更簡單...您可以使用-in
運營商在Where
聲明是這樣的:
$services | Where{$_ -in $masterList} | ForEach{"$_ match found"}
,基本上篩選$services
陣列以查找$masterList
陣列中的任何字符串。這將只適用於完全匹配,但!因此,如果該服務被列爲「OPS-AmazonServer」,但是在您的CSV文件中列出的只是'AmazonServer',它將無法使用!我特別使用這個例子,因爲你在你的問題中有你的例子。您專門調用名爲「OPS-AmazonServer」的服務,然後在您的CSV示例中列出「AmazonServer」。
如果CSV中的列表是您想要匹配的部分字符串,您可以使用RegEx來執行此操作。如果您對RegEx不熟悉,這可能意義不大,但這會起作用:
$services = Get-Service -ComputerName $serverName | Where{$_.Name -like 'ops*' -or $_.Name -like 'Centinel*'} | Select -Expand Name
$masterList = (Import-Csv $csvLocation | ForEach{[regex]::escape($_.ApplicationName)}) -join '|'
$services | Where{ $_ -match $masterList } | ForEach{"$_ match found"}
您提供的示例中未定義/分配'$ services'嗎?另外,如果csv列中有一個空格,則需要引用它:'$ _。'Application Name'' –
您說你正在存儲Windows服務。如果是來自'Get-Service' cmdlet,則需要在比較中指定每個服務的屬性,例如$ service.name或$ service.DisplayName,具體取決於該CSV的內容是什麼。 – TheMadTechnician
@ MathiasR.Jessen編輯OP以獲得更好的說明。我很抱歉,我是新來的Stackoverflow –