Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Combine multiple logical operators

Is there a way to combine parameters for multiple logical operators in a where statement?

Basically I have a statement like this:

<command chain> | where {$_.user.tostring() -ne "USER1" -and $_.user.tostring() -ne "USER2" -and $_.user.tostring() -ne "USER3"}

It's actually a fairly long chain, so I'd like to simplify it so that it becomes something like this:

<command chain> | where {$_.user.tostring() -ne {"USER1" -or "USER2" -or "USER3"}}

The above statement doesn't work, so any suggestions please on how to go about this?

like image 489
d3Xt3r Avatar asked Sep 28 '15 02:09

d3Xt3r


2 Answers

Assuming your dealing with a array it can be done in this similar fashion you wrote it, even shorter check this out:

PS Z:\> @("food","drink","cheese","dog") -match "(food|cheese)"
food
cheese

PS Z:\> @("food","drink","cheese","dog") -notmatch "(food|cheese)"
drink
dog

where clause:

PS Z:\> @("food","drink","cheese","dog") | where {$_ -notmatch "(food|cheese)"}
drink
dog
like image 32
Subdee Avatar answered Sep 22 '22 03:09

Subdee


You want to use this:

where {$_.user.tostring() -notin ("USER1","USER2","USER3")}

Or this:

where {($_.user.tostring() -ne "USER1") -and ($_.user.tostring() -ne "USER2") -and ($_.user.tostring() -ne "USER3") }

That's really about as simple as you can get. The boolean operators should, in general, only be used to combine comparison operators (or other things you know represent boolean values).


Your code here:

where {$_.user.tostring() -ne {"USER1" -or "USER2" -or "USER3"}}

This is basically nonsense. It's always going to evaluate to true. {"USER1" -or "USER2" -or "USER3"} is of datatype ScriptBlock.

PS C:\> ({"USER1" -or "USER2" -or "USER3"}).GetType().FullName
System.Management.Automation.ScriptBlock

I believe PowerShell will cast this to a string, but even if it gets cast to a string, it's still not evaluated as a boolean expression:

PS C:> ({"USER1" -or "USER2" -or "USER3"}).ToString()
"USER1" -or "USER2" -or "USER3"

That's going to evaluate to True unless the user is literally '"USER1" -or "USER2" -or "USER3"'

If you changed it so that it was a parenthetic expression instead of a script block:

where {$_.user.tostring() -ne ("USER1" -or "USER2" -or "USER3")}

Then it would always be true. ("USER1" -or "USER2" -or "USER3") is of type Boolean, and will always have the value of true.

PS C:\> ("USER1" -or "USER2" -or "USER3")
True

So you're basically running:

where {$_.user.tostring() -ne $true }

Again, even if PowerShell converts everything to a string like I think it will, it's pretty unlikely you've got a user named "True". So this will always be true.

like image 155
Bacon Bits Avatar answered Sep 23 '22 03:09

Bacon Bits