This is a general feature of PowerShell's comparison operators:
With a scalar (single) LHS operand, they return a [bool]
result ($true
or $false
).
With an array (collection) LHS operand, they act as filters and return those LHS elements that match, (invariably) as an array.
With respect to the -match
operator, specifically, note that the automatic $Matches
variable, which contains information about what was matched, is only populated with a scalar LHS.
As iRon points out, PowerShell's implicit to-Boolean coercion rules also allow you to use operations with array-valued LHS as conditionals; e.g.:
# -> 'MATCH found',
# because the -match operation returns @('foo'), i.e.
# the subarray of matching items, and [bool] @('foo') is $true.
if (@('foo', 'bar') -match 'f') { 'MATCH found' } else { 'NO match' }
# -> 'NO match',
# because the -match operation returns @(), i.e. an *empty array,
# and [bool] @() is $false
if (@('foo', 'bar') -match 'x') { 'MATCH found' } else { 'NO match' }
However, there are pitfalls, namely when the filtering operation returns a single result that happens to be $false
when coerced to [bool]
Note that even though a single-element array is returned in that case, PowerShell treats it the same as its one and only element in this context:
# !! -> 'NO match', even though a match *was* found:
# !! The -match operation returns @('') and [bool] @('') is the
# !! same as [bool] '' and therefore $false.
if (@('', 'bar') -match 'foo|^$') { 'MATCH found' } else { 'NO match' }
# !! -> 'NO match', even though a match *was* found:
# !! The -eq operation returns @(0) and [bool] @(0) is
# !! the same as [bool] 0 and therefore $false.
if (@(0, 1) -eq 0) { 'MATCH found' } else { 'NO match' }
If two or more results are returned, the coercion result is always $true
, however, irrespective of the value of the array elements (analogous to how no results, i.e. an empty return array, always yields $false
).
A summary of PowerShell's to-Boolean conversion rules is in the bottom section of this answer.