Using Conditional Operators with “-not(match|like)”
I recently answered a post on PoshComm about the use of -or and -and. There was a little confusion on the expected results as this gets especially confusing when using ‘-not’, ‘-notmatch’, or ‘-notlike’. It is effectively a difference between “Include ALL but x” vs “Exclude ALL but x.”
The key to understanding how ‘-or’ and ‘-and’ will work is understanding that everything evaluates to $true or $false and this value is returned for EVERY condition check independantly. Working from the inside (left to right) to the outside (left to right.)
Here is an example of outter and inner conditions.
where(
# inner Condition 1 (Processed First)
($description -notmatch "TestOne")
-or
# inner Condition 2 (Processed Second)
($description -notmatch "AnotherTest")
)
Below is a some working code that will illustrate the point.
The goal is to find all the descriptions that do not match ‘TestOne’ or ‘AnotherTest’.
$myDescriptions = @("My Description has an ‘TestOne’ in it")
1..2 | %{$myDescriptions += "Really descriptive ’s$_’ description"}
$myDescriptions += "My Description has an ‘AnotherTest’ in it"
foreach($description in $myDescriptions)
{
$matchTestOne = $description -notmatch "TestOne"
$matchAnotherTest = $description -notmatch "AnotherTest"
$UsingOr = ($description -notmatch "TestOne") -or ($description -notmatch "AnotherTest")
$UsingNotMatchCorrectly = $description -notmatch "(TestOne|AnotherTest)"
"Value: $description"
"Match One: $matchTestOne"
"Match Two: $matchAnotherTest"
"The Or: $UsingOr"
"Using NotMatch Correctly: $UsingNotMatchCorrectly"
Write-Host
}
Here is the output from the above code. Notice that $UsingOr does not return as the one might expected. This is because every description will pass at least one of the conditions and therefore the entire condition will return $true.
Match One: False
Match Two: True
The Or: True
Using NotMatch Correctly: False
Value: Really descriptive ’s1′ description
Match One: True
Match Two: True
The Or: True
Using NotMatch Correctly: True
Value: Really descriptive ’s2′ description
Match One: True
Match Two: True
The Or: True
Using NotMatch Correctly: True
Value: My Description has an ‘AnotherTest’ in it
Match One: True
Match Two: False
The Or: True
Using NotMatch Correctly: False


Another code I already saw few times on different blogs\forums is:
Get-Process | Where {$_.ProcessName -eq “explorer” -or “iexplore”}
Instead of
Get-Process | Where {($_.ProcessName -eq “explorer”) -or ($_.ProcessName -eq “iexplore”)}
If is expanded to condition ‘If ProcessName is explorer OR “iexplore” is object’, which is of course always $true.
Not sure however how is following interpreted in PS:
Get-Process | Where {$_.ProcessName -eq (“explorer” -or “iexplore”)}
Martin
(”explorer” -or “iexplore”) will always be true.
$_.ProcessName will never -eq $true
Thus this will never return any results.
The best way to do this is this.
Get-Process | where {$_.ProcessName -match “(e|ie)xplore”}
or
Get-Process | where {$_.ProcessName -match “explorer|iexplore”}