I am having trouble coming up with a way to do complex logic using the where-object in PowerShell
I have the following code, but separating the and from the ORs is not working as intended.
Get-ADComputer -Filter * | Where-Object {
($_.Enabled) -and
(($_.DistinguishedName -contains 'world') -or
($_.DistinguishedName -contains 'foo')) -and
(($_.SID -contains 'bar') -or
($_.SID -contains 'something else'))
}
If I do this in c# I get results, but in powershell I do not.
Any thoughts on how to get around this?
TIA
The main issue is very likely with -contains, this is the operator you would use to check whether an item exists in an array, for example:
'apple', 'banana', 'pineapple' -contains 'apple'
# True
This operator does not work in partial matches, only exact ones. For partial matches you could use -like or, the recommended one in this case would be the -match operator with a regex OR pattern:
Get-ADComputer -Filter 'enabled -eq $true' | Where-Object {
$_.DistinguishedName -match 'world|foo' -and
$_.SID -match 'bar|something else'
}
Using -like the condition becomes very similar as what you currently have, however you do need the * wildcards (for the partial match), no parentheses are needed:
Get-ADComputer -Filter 'enabled -eq $true' | Where-Object {
$_.DistinguishedName -like '*world*' -or $_.DistinguishedName -like '*foo*' -and
$_.SID -like '*bar*' -or $_.SID -like '*something else*'
}
If Where-Object isn't performing well (it can be slow), you might consider a more classic approach using foreach and if conditions:
$result = foreach ($computer in Get-ADComputer -Filter 'enabled -eq $true') {
if ($computer.DistinguishedName -match 'World|Foo' -and $computer.SID -match 'bar|something else') {
$computer
}
}