Friday, May 27, 2016

PowerShell v3 in a Year Day 2 Where Object

Topic: Where-Object
Alias: ?, where

? is an alias for the Where-Object cmdlet in PowerShell. As noted in the help, Where-Object "[s]elects objects from a collection based on their property values." In version 2 PowerShells Where-Object only had 10 parameters, but, since one of these was the set of 8 common parameters, it was really 2.

  • FilterScript
  • InputObject
  • CommonParameters (the usual 8 suspects)

Most of the time, you used Where-Object with a pipeline and put some sort of comparison operator in the FilterScript. For instance, if you wanted to see if a file existed in a folder you could use this approach where the pipelined object was the InputObject,
dir | Where {$_.name -eq index.dat}
In version 3, the cmdlet has 31 parameter sets and 34 parameters. Below is a complete list of the parameters you have the option to work with in PowerShell:

  • CContains
  • CEQ
  • CGE
  • CGT
  • CIn
  • CLE
  • CLike
  • CLT
  • CMatch
  • CNE
  • CNotContains
  • CNotIn
  • CNotLike
  • CNotMatch
  • Contains
  • EQ
  • FilterScript
  • GE
  • GT
  • In
  • InputObject
  • Is
  • IsNot
  • LE
  • Like
  • LT
  • Match
  • NE
  • NotContains
  • NotIn
  • NotLike
  • NotMatch
  • Property
  • Value
As with the ForEach-Object post I put up yesterday, the syntax for Where-Object has changed a bit, and, with them, the rules used to use the cmdlet. For instance, in v2, you could have done this,
dir C:windowssystem32 | Where {$_.name -like cmd.exe}
can now be executed in v3 with this command,
 dir C:windowssystem32 | Where -Property name -like cmd.exe
The need for curly braces is no longer present in v3. In this case we see a special new parameter, -Property,  which gives you the ability to zero in on a specific property where before you needed to use the pipeline variable, $_, and use dot referencing to access the property. This change, as with many others in v3, are designed to simplify the learning of PowerShell syntax.

While you can still use the v2 syntax, the sheer number of operators with which you can approach comparisons now make the old approach outdated. The one case where you still need to rely on the old syntax is when you have multiple conditions in your filter. One of the key differences between v2 and v3 is now there are two ways you can construct Where-Object statements:

  1. Script block: these are the old v2 approach, where you specify a property name, an operator and a property value to compare. Any item that is evaluated as being $true is returned.
  2. Comparison statements: this new v3 approach allows you to write comparison statements which are much closer to natural language. 
Below are two differently structured comparison statements whose results would be identical:
Get-Process | Where-Object -Property PriorityClass -eq -Value "Normal"
Get-Process | Where-Object PriorityClass -eq "Normal"
Note that you do not need to specify the parameters in the second example and the cmdlet still works exactly the same.

If you pull up the Get-Help for v3, you will notice that just about every parameter in v3 is new. Even though they are new, the basic trick to understanding how to use them is to imagine taking a normal v2 Where-Object cmdlet, and, stripping off the braces and $_ variable. Just as you would use it to see if a file name was equal to a value in v2 with the -eq operator, the braces and the pipeline variable, you accomplish the same thing just as easily with the new -eq operator. The same is true of the other operators we would normally place in a script block.

Many of the operators that have been standardized as full-blown operators for the Where-Object cmdlet are quite familiar. There are a few I find pretty interesting. Particularly, I like:

  • -In
  • -NotIn
  • -CIn
  • -CNotIn
  • -Is
  • -IsNot
Most of the others already existed in some form or another, but, these are pretty cool. Lets say, for instance, you need to see how many instances of notepad are running. You can use Get-Process and pipe it to Where-Object with these options,
Get-Process | where -Value notepad -In -Property ProcessName
In the past, you would have run the command this way:
 Get-Process | where {$_.ProcessName -eq notepad}
While the difference between the two is nothing apparent, like an obviously shorter command, the simpler syntax, and, logical power of these new operators gives you flexibility v2 PowerShell users did not have the ability to take advantage of.  Many of the filters will not be obviously beneficial at first, but, subtle cases will demonstrate the underlying benefits of the new array of operators.


Related Post:

0 comments:

Post a Comment

 
Copyright 2009 Information Blog
Powered By Blogger