5

#PSTip PowerShell 4 – Filtering a collection by using a method syntax

Note: This tip requires PowerShell 3.0 or above.

One of the new features introduced in PowerShell 4.0 is the collection filtering by using a method syntax. You can now filter a collection of objects using a simplified Where-Object like syntax specified as a method call.

PS> (Get-Process).where("name -like p*")

Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
-------  ------    -----      ----- -----   ------     -- -----------
    465      30    86396     100996   624     2.56   9524 powershell
    893      91   346044     382620  1050   515.21   9736 powershell_ise

Awesome! Now, if you open PowerShell and try this out you’ll probably get the following error:

PS > (Get-Process).where("name -like p*")
Method invocation failed because [System.Diagnostics.Process] does not contain a method named 'where'.
At line:1 char:1
+ (gps).where("name -like p*")
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : MethodNotFound

What happened? Collection filtering is a part of the PSDesiredStateConfiguration module and to have it available you first need to import the module.

PS> Import-Module PSDesiredStateConfiguration
PS> (Get-Process).where("name -like p*")

Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
-------  ------    -----      ----- -----   ------     -- -----------
    709      66   138168     163976   744     5.24   7120 powershell
    893      91   346044     382620  1050   515.21   9736 powershell_ise

# now let's examine the method signature:
PS>  (Get-Process).where

Script              :
                               $prop, $psop, $val = [string] $args[0] -split '(
                      -eq|-ne|-gt|-ge|-lt|-le|-like|-notlike|-match|-notmatch)'
                               $operation = @{ Prop = $prop.Trim(); Value =
                      $val.Trim(); $psop = $true }
                               $this | where @operation

OverloadDefinitions : {System.Object where();}
MemberType          : ScriptMethod
TypeNameOfValue     : System.Object
Value               : System.Object where();
Name                : where
IsInstance          : False

As you can see the where method is actually a ScriptMethod, and if you open the PSDesiredStateConfiguration psm1 file you’ll find the command that extends the System.Array type using the Update-TypeData cmdlet (line 849).

    Update-TypeData -Force -MemberType ScriptMethod -MemberName where -TypeName System.Array -Value {
         $prop, $psop, $val = [string] $args[0] -split '(-eq|-ne|-gt|-ge|-lt|-le|-like|-notlike|-match|-notmatch)'
         $operation = @{ Prop = $prop.Trim(); Value = $val.Trim(); $psop = $true }
         $this | where @operation
    }

Having to load the module each time you want to use the method is not that convenient so why not adding it to every PowerShell session you open. Add the above command to your profile and you’re good to go.

where() method is not limited to PowerShell 4.0 only. Simplified syntax was introduced in PowerShell 3.0 so you can enable this on systems with that version as well.

Filed in: Columns, Tips and Tricks Tags: , , ,

One Pingback/Trackback

5 Responses to "#PSTip PowerShell 4 – Filtering a collection by using a method syntax"

  1. nohandle says:

    Nice tip. From the name of the module I assume this way of calling where was introduced to comply with PS DSC “coding style”, right? Otherwise I personally don’t see why I should prefer to use this over where {}, it does not even support all the operators.

    • PowerShellMag says:

      Thanks. The syntax was first introduced in Snover’s DSC presentation and as you can see under the hood it is calling the Where-Object cmdlet. The method syntax complies to the the same rules of Simplified syntax (the limitation of using an expression of just one operator). In my opinion, Using it or not is, is just a matter of preference.

      • nohandle says:

        Well, to me it looks even more restricted, the Simplified syntax supports -in, -is, all case-sensitive versions of the operators etc., this method does not. Anyway good to know the limitations, I will introduce the DSC to my colleagues as a great feature to consider in our future deployments.

        • PowerShellMag says:

          Yes, the list of supported parameters doesn’t match the ones of the Where-Object cmdlet, they are just the most common used imo.

Leave a Reply

Submit Comment

© 2059 PowerShell Magazine. All rights reserved. XHTML / CSS Valid.
Proudly designed by Theme Junkie.
%d bloggers like this: