Where-object in PowerShell v3
Where-Object – aliased to where, but never, ever, ever, ever to ? – had a very simple syntax in PowerShell v2
Where-Object [-FilterScript] <scriptblock> [-InputObject <psobject>] [<CommonParameters>]
It was normally used as
Get-Process | where {$_.CPU -gt 25}
The –FilterScript parameter (positional as 1 so don’t have to use it) supplies a script block that performs the filtering. In this case it looks at the current object on the pipeline (indicated by $_) and compares the CPU property to 25. If the property has a greater value it is passed.
Any of the comparison operators could be used in the filter block.
With PowerShell v3 it gets easier
Get-Process | where CPU -gt 25
We can just give the property name, the comparison operator and the value.
This only works for a single property. You can’t do this
PS> Get-Process | where CPU -gt 25 -and Handles -gt 2000
Where-Object : Cannot bind parameter because parameter 'gt' is specified more than once. To provide multiple values to
parameters that can accept multiple values, use the array syntax. For example, "-parameter value1,value2,value3".
At line:1 char:45
+ Get-Process | where CPU -gt 25 -and Handles -gt 2000
+ ~~~
+ CategoryInfo : InvalidArgument: (:) [Where-Object], ParameterBindingException
+ FullyQualifiedErrorId : ParameterAlreadyBound,Microsoft.PowerShell.Commands.WhereObjectCommand
You have to go back to
Get-Process | where {$_.CPU -gt 25 -and $_.Handles -gt 2000}
but hang on a minute the error message said that gt is a parameter!
If you look at the help file for where-object you will see lots of lines like this
Where-Object [-FilterScript] <ScriptBlock> [-InputObject <PSObject>] [<CommonParameters>]
Where-Object [-Property] <String> [[-Value] <Object>] [-EQ [<SwitchParameter>]] [-InputObject <PSObject>] [<CommonParameters>]
Where-Object [-Property] <String> [[-Value] <Object>] [-InputObject <PSObject>] -Contains [<SwitchParameter>] [<CommonParameters>]
Where-Object [-Property] <String> [[-Value] <Object>] [-InputObject <PSObject>] -GE [<SwitchParameter>] [<CommonParameters>]
Where-Object [-Property] <String> [[-Value] <Object>] [-InputObject <PSObject>] -In [<SwitchParameter>] [<CommonParameters>]
Where-Object [-Property] <String> [[-Value] <Object>] [-InputObject <PSObject>] -CContains [<SwitchParameter>] [<CommonParameters>]
Where-Object [-Property] <String> [[-Value] <Object>] [-InputObject <PSObject>] -CEQ [<SwitchParameter>] [<CommonParameters>]
Where-Object [-Property] <String> [[-Value] <Object>] [-InputObject <PSObject>] -CGE [<SwitchParameter>] [<CommonParameters>]
Where-Object [-Property] <String> [[-Value] <Object>] [-InputObject <PSObject>] -CGT [<SwitchParameter>] [<CommonParameters>]
Where-Object [-Property] <String> [[-Value] <Object>] [-InputObject <PSObject>] -CIn [<SwitchParameter>] [<CommonParameters>]
Where-Object [-Property] <String> [[-Value] <Object>] [-InputObject <PSObject>] -CLE [<SwitchParameter>] [<CommonParameters>]
Where-Object [-Property] <String> [[-Value] <Object>] [-InputObject <PSObject>] -CLike [<SwitchParameter>] [<CommonParameters>]
Where-Object [-Property] <String> [[-Value] <Object>] [-InputObject <PSObject>] -CLT [<SwitchParameter>] [<CommonParameters>]
Where-Object [-Property] <String> [[-Value] <Object>] [-InputObject <PSObject>] -CMatch [<SwitchParameter>] [<CommonParameters>]
Where-Object [-Property] <String> [[-Value] <Object>] [-InputObject <PSObject>] -CNE [<SwitchParameter>] [<CommonParameters>]
Where-Object [-Property] <String> [[-Value] <Object>] [-InputObject <PSObject>] -CNotContains [<SwitchParameter>] [<CommonParameters>]
Where-Object [-Property] <String> [[-Value] <Object>] [-InputObject <PSObject>] -CNotIn [<SwitchParameter>] [<CommonParameters>]
Where-Object [-Property] <String> [[-Value] <Object>] [-InputObject <PSObject>] -CNotLike [<SwitchParameter>] [<CommonParameters>]
Where-Object [-Property] <String> [[-Value] <Object>] [-InputObject <PSObject>] -CNotMatch [<SwitchParameter>] [<CommonParameters>]
Where-Object [-Property] <String> [[-Value] <Object>] [-InputObject <PSObject>] -Is [<SwitchParameter>] [<CommonParameters>]
Where-Object [-Property] <String> [[-Value] <Object>] [-InputObject <PSObject>] -IsNot [<SwitchParameter>] [<CommonParameters>]
Where-Object [-Property] <String> [[-Value] <Object>] [-InputObject <PSObject>] -LE [<SwitchParameter>] [<CommonParameters>]
Where-Object [-Property] <String> [[-Value] <Object>] [-InputObject <PSObject>] -Like [<SwitchParameter>] <CommonParameters>]
Where-Object [-Property] <String> [[-Value] <Object>] [-InputObject <PSObject>] -LT [<SwitchParameter>] <CommonParameters>]
Where-Object [-Property] <String> [[-Value] <Object>] [-InputObject <PSObject>] -Match [<SwitchParameter>] [<CommonParameters>]
Where-Object [-Property] <String> [[-Value] <Object>] [-InputObject <PSObject>] -NE [<SwitchParameter>] [<CommonParameters>]
Where-Object [-Property] <String> [[-Value] <Object>] [-InputObject <PSObject>] -NotContains [<SwitchParameter>] [<CommonParameters>]
Where-Object [-Property] <String> [[-Value] <Object>] [-InputObject <PSObject>] -NotIn [<SwitchParameter>] [<CommonParameters>]
Where-Object [-Property] <String> [[-Value] <Object>] [-InputObject <PSObject>] -NotLike [<SwitchParameter>] [<CommonParameters>]
Where-Object [-Property] <String> [[-Value] <Object>] [-InputObject <PSObject>] -NotMatch [<SwitchParameter>] [<CommonParameters>]
The first option is the PowerShell v2 version.
Notice that the comparison operators are switch parameters and each is in a different parameter set – thats why you can’t have multiples
This is a very useful addition to where-object that simplifies syntax (we often only perform a single comparison in the filter) and reduces typing.
It still doesn’t change the fact that you should never, ever, ever, ever alias where-object to ?