PowerShell has a unique variable called the pipeline variable ($_ or $PSItem). Due to PowerShell's ability to pipe entire objects from one command to another, it needed a way to represent that object that was traversing the pipeline.

Adam Bertram

Adam Bertram is a 20-year IT veteran, Microsoft MVP, blogger, and trainer. Adam is the founder of the e-learning tech screencast platform TechSnips. Catch up on Adam’s articles at adamtheautomator.com, or follow TechSnips on Twitter at @techsnips_io.

When one PowerShell command pipes something to another command, that command can send an object. An object can be of any type. That object then has a set of methods and properties attached to it. We can reference those methods and properties on a standalone object by creating the object, assigning it to a variable, and then referencing its properties and methods that way.

For example, the Get-Item cmdlet returns a System.IO.DirectoryInfo object when querying a directory.

Using Get Item to query a directory

Using Get Item to query a directory

This object then has lots of different methods and properties we can reference. I could call methods on this object or reference its properties.

Simple enough, right? But, what if I'm using a cmdlet like Get-ChildItem, which enumerates lots of directories at once? It'd be crazy to assign variables like $dir1, $dir2, and $dir3 to all of them. We need a more dynamic way to represent them. We need a single variable that represents each directory object upon processing it. We need the pipeline variable!

Using the Get-ChildItem example, let's say I want to find all directories in the C:\Windows folder using Get-ChildItem -Path C:\Windows\ -Directory. This command returns a few dozen directories. If we'd assign this output to a variable, it'd be an array of objects, not just a single object. Instead, I can pipe all of those objects, one at a time, from Get-ChildItem to ForEach-Object and reference the pipeline variable.

The pipeline variable ($_ or $PSItem) represents each object upon processing it. You can see below that I can reference the Name property for every directory processed using $_.Name.

With the pipeline variable, we can reference any method and property. The variable will always be of the same type as the object coming from the previous command. You can see below that if you pipe the pipeline variable itself to Get-Member, it returns the same System.IO.DirectoryInfo object type as Get-Item.

You'll see the pipeline variable most often used in commands that need to reference or perform some specific action on each object processed. Another example is using the Select-Object cmdlet's calculated properties. This allows the scripter to manipulate the output returned by referencing objects from the pipeline.

For example, instead of using ForEach-Object to return only the directory names, I could use a calculated property to create a DirectoryName property on the fly and assign the directory names to that.

Thus, we can use the pipeline variable in many different scenarios. In what scenarios do you use the pipeline variable?

Join the 4sysops PowerShell group!

1+
Share
5 Comments
  1. carlos 1 year ago

    Hey, thanks for the post. one fast question.

    How i can take the object from the first comands of the pipeline? for example imagine i do thisç

    Get-mailboxdatabase | get-mailbox | get-mailboxstatistics | select object "objectfrom get-mailbox" "objectfrom get-mailboxstatistics" "object from mailboxdatabase"

    Dont know if i explain well. and sorry for my english, not native speaker here.

     

    2+

  2. Simon 5 months ago

    I am interested in the answer to this too.

    When we pipeline two or more commands together we end up with only the properties of the last command in the chain.

    Example:

    command1 | command2 | fl

    results in;

    Command2 property 1 : 

    Command2 property 2 : 

    Command2 property 3 :

    etc. 

    Very often we need properties from the preceding commands to build the desired output.

    The way I usually do this is to assign the output of each command to a variable then tie the two together at the end.

    $variable1 = command1

    $variable2 = command1 | command2

    To be able to use this we need a common field between the two commands to link them together or more usually a foreach loop. This is massively inefficient.

    So to reiterate Carlos' question I think what we are looking for is something along the lines of

    command1 | command2 | ft

    output:

    command1.property1

    command1.property2

    command2.property1

    command2.property2

    0

  3. Luc Fullenwarth 5 months ago

    @Simon

    You can do this with the -OutVariable parameter (when it has been implemented).

    This command line displays the result of the third cmdlet.

    However, $FirstResult stores the result of the first cmdlet and $SecondResult stores the result of the second cmdlet.

    Please note that when you use the -OutVariable parameter you must omit the $ sign.

    This does not work

     

    0

  4. Martin 2 months ago

    In recent powershell versions, there's also specific parameter called -PipelineVariable (alias pv). See:

    1+

    Users who have LIKED this comment:

    • avatar
    • Swapnil Kambli 2 months ago

      True. PipelineVariable introduced in PowerShell 4.0 helps further optimize the code for parameter management.

      0

Leave a reply

Your email address will not be published. Required fields are marked *

*

© 4sysops 2006 - 2019

CONTACT US

Please ask IT administration questions in the forums. Any other messages are welcome.

Sending

Log in with your credentials

or    

Forgot your details?

Create Account