好,最容易做到这一点的方法是使用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 –