PowerShell has two operators that do very similar jobs –contains and –in. So which should you use –contains or –in.
From the help file.
-Contains: Tells whether a collection of reference values includes a single test value.
-In: Tells whether a test value appears in a collection of reference values
OK – they’re subtly different.
The real difference comes in how you use them
-Contains has been available since PowerShell v1. Its used like this
<reference values> –contains <value>
for example
PS> $rb = ‘Red’, ‘Orange’, ‘Yellow’, ‘Green’, ‘Blue’, ‘Indigo’, ‘Violet’
PS> $rb -contains ‘yellow’
True
PS> $rb -contains ‘black’
False
True or false is returned depending if the value is part of the collection or not
By contrast –In (introduced in PowerShell v3) uses this syntax
<value> –in <reference values>
for example
PS> $rb = ‘Red’, ‘Orange’, ‘Yellow’, ‘Green’, ‘Blue’, ‘Indigo’, ‘Violet’
PS> ‘Blue’ -in $rb
True
PS> ‘Black’ -in $rb
False
The difference between the two is the order of the operands.
-In was introduced for use with the short hand syntax of Where-Object
where <property value> operator <value>
so try this
$rb = ‘Red’, ‘Orange’, ‘Yellow’, ‘Green’, ‘Blue’, ‘Indigo’, ‘Violet’
$colours = ‘Black’, ‘White’, ‘Red’
$co = foreach ($colour in $colours) {
New-Object -TypeName psobject -Property @{
Colour = $colour
}
}
Then run
$co | where Colour -in $rb
$co | where Colour -contains $rb
$co | where $rb -contains colour
$co | where {$rb -contains $_.colour}
You’ll see the correct answer from the first and fourth options and nothing from the second because the values are the wrong way round. The third option errors
Where-Object : A positional parameter cannot be found that accepts argument
‘System.Object[]’.
At line:1 char:7
+ $co | where $rb -contains colour
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Where-Object], ParameterBi
ndingException
+ FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell
.Commands.WhereObjectCommand