0

I have a string array $Exclude which I want to put into a filter in a Get-WMIObject cmdlet. I have added it at the end but it does not work.

How can I filter out the services that are listed in that array?

$ServicesToExclude = "RemoteRegistry,CpqNicMgmt"
$Exclude = $ServicesToExclude.split(",")
$Services = Get-WmiObject -Class Win32_Service -Filter {State != 'Running' and StartMode = 'Auto' and Name -ne $Exclude} 


$Result =    foreach ($Service in $Services.Name) 
    { 
          Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\$Service" | 
            Where-Object {$_.Start -eq 2 -and $_.DelayedAutoStart -ne 1}| 
            Select-Object -Property @{label='ServiceName';expression={$_.PSChildName}} | 
            get-Service 

        }

If ($Result.count -gt 0){
$Displayname = $Result.displayname
[string]   $Line = "`n-----------------------------------------"

$Api.LogScriptEvent( 'Stopped_Auto_Services.ps1',1234,4,"`nStopped Automatic Services$Line `n$($Displayname)")

2 Answers 2

2

Filtering an array out of a list is not done on the WMI side. Instead, you should use Where-Object to filter out those services which name is contained in $Exclude.

$Services = Get-WmiObject -Class Win32_Service -Filter {State != 'Running' and StartMode = 'Auto'} |
Where-Object {$Exclude -notcontains $_.Name}
Sign up to request clarification or add additional context in comments.

3 Comments

I like this reverse logic for Where-Object!
@ALIENQuake Well, it's kinda obvious, since Where-Object passes only those objects that return true against query. I could write {-not ($Exclude -contains $_.name)}, no difference, and why using this if there's a built in -notcontains comparator?
Ye, but I've never use it in such way. I've always use single element inside Where-Object. Being able to use array there will simplify many things.
0

WMI queries do not work well with arrays and need to be done a different way. If you want to keep the filtering on the server side, you can do some work prior to running the command by creating a filter string as shown here:

$Exclude = "RemoteRegistry","CpqNicMgmt"
$StringBuilder = New-Object System.Text.StringBuilder
[void]$StringBuilder.Append("State != 'Running' AND StartMode = 'Auto' AND ")
[void]$StringBuilder.Append("($(($Exclude -replace '^(.*)$','Name != "$1"') -join ' AND '))")
$Query = $StringBuilder.ToString()
$Services = Get-WmiObject -Class Win32_Service -Filter $Query

There may be better ways to accomplish this, but this was the first thing that I could think of to accomplish the goal of your question.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.