Matthias Güntert
Matthias Güntert

Reputation: 4640

PowerShell: How to apply multiple filters via where-object cmdlet?

Is there a better way to filter for objects via where-object then to send the data through multiple pipelines?

$clients = Get-ADComputer 
                -SearchBase "OU=Clients,DC=contoso,DC=com" 
                -Filter * 
                -Properties Description,OperatingSystem

$clients | Where OperatingSystem -notlike "*Windows 7*" 
                 | Where OperatingSystem -notlike "*Windows 10*"  

Ideal would be a complex filtering mechanism like we can use for the -Filter Parameter. I would have expected to be able to use something like the following...

$Clients | Where { 
    (OperatingSystem -notlike "Windows 7") -and (OperatingSystem -notlike "Windows 10")
}

Upvotes: 1

Views: 15131

Answers (3)

Bacon Bits
Bacon Bits

Reputation: 32145

$clients | Where OperatingSystem -notlike "*Windows 7*" |
    Where OperatingSystem -notlike "*Windows 10*"  

Strictly speaking, this should work.

However, the problem you're running in to is that the simplified Where-Object syntax shown above only works in the most simple cases. When you use the full syntax, you must specify the properties using the $_ variable:

$clients | Where-Object {
    ($_.OperatingSystem -notlike '*Windows 7*') -and ($_.OperatingSystem -notlike '*Windows 10*')
}

However, since you're using Get-ADComputer, you really should be using the -Filter property on that command. It will be much faster, and will be less work for your domain controller, too:

Get-ADComputer -SearchBase "OU=Clients,DC=contoso,DC=com" `
    -Filter "(OperatingSystem -notlike '*Windows 7*') -and (OperatingSystem -notlike '*Windows 10*')" `
    -Properties Description,OperatingSystem

Upvotes: 3

Bill_Stewart
Bill_Stewart

Reputation: 24525

It is more efficient to filter directly in the query rather than filtering after-the-fact using Where-Object (which retrieves all objects first). Example using the -LDAPFilter parameter:

Get-ADComputer -LDAPFilter "(&(!operatingSystem=Windows 7*)(!operatingSystem=Windows 10*))" -Properties operatingSystem,description

Upvotes: 1

ps1psm1
ps1psm1

Reputation: 144

Something like this perhaps?

$DesktopClients=@('Windows 7','Windows 10')
$Clients=$Clients -notmatch ($DesktopClients -join '|')

Upvotes: -1

Related Questions