Shorten Where-Object

Hi,

I am relatively new to PowerShell and couldn’t figure out how to shorten this command in “splat-style” shortening so it would read better, is there a way?

gwmi win32_service -ComputerName $servers -filter “StartMode = ‘Auto’ and State ‘Running’” | where-object{($.DisplayName -ne “Software Protection”) -and ($.DisplayName -ne “Shell Hardware Detection”) -and ($.DisplayName -ne “Microsoft .NET Framework NGEN v4.0.30319_x86”) -and ($.DisplayName -ne “Microsoft .NET Framework NGEN v4.0.30319_x64”)} | ft SystemName, DisplayName

I tried to assign everything inside the {} to a variable and then run it like that but that didn’t work too well.

Any suggestions would be appreciated.

Thanks
AC

Well, you could build an array of strings and use the -notcontains operator:

$exclude = "Software Protection", "Shell Hardware Detection", "Microsoft .NET Framework NGEN v4.0.30319_x86", "Microsoft .NET Framework NGEN v4.0.30319_x64"

gwmi win32_service -ComputerName $servers -filter "StartMode = 'Auto' and State != 'Running'" |
Where-Object { $exclude -notcontains $_.DisplayName }
ft SystemName, DisplayName

However, it’s generally better to put all of this logic right into your -Filter string, for performance reasons. In that case, you can’t use the array directly, but you can build up a filter string dynamically from the array. For example:

$exclude = "Software Protection", "Shell Hardware Detection", "Microsoft .NET Framework NGEN v4.0.30319_x86", "Microsoft .NET Framework NGEN v4.0.30319_x64"

$excludeAsString = @($exclude | ForEach-Object { "DisplayName != ""$_""" }) -join ' AND ' 

gwmi win32_service -ComputerName $servers -filter "StartMode = 'Auto' and State != 'Running' AND $excludeAsString" |
ft SystemName, DisplayName

Thank you Dave, that works perfectly!