Back to basics: The pipeline

Here we go again! Another Power The Shell blog post.

Today, let’s go back to basics ! We’ll talk about the pipeline. If I read the definition in a dictionary, it’s common sense for another people out of the PowerShell business that it’s something that is transporting gasoil from one point to another. Well, it’s not as far as PowerShell idea of pipeline, the main change is that in PowerShell objects are passed through the pipe (we’ll call it the pipe from now on, easier to say, and less letters to type).

In all versions of PowerShell, pipe the return of a cmdlet the simplest task ever !

Get-Process | Format-List

How does it work ?

But now, how do we treat each values passed down the pipe, how can retrieve theses values to play with them ?

This is where the $_ variable show her face. This variable will contains the value of the current piped object, it means all, properties and members are available. But this nothing is not enough. You will have to tell PowerShell if you want using the Where-Object or the Foreach-Object cmdlet ! The Where-Object is more likely a filter which will gather results match the value. The Foreach-Object is the opposite, and you will start an action for each piped values, examples.

Get-Process | Where-Object {  $_ -like “*a*” }
#Or
Get-Process | Foreach-Object {  Write-Output $_ }

But, how is it working if we pipe multiple object into multiple pipes ? Even it is possible ? Let’s try this !

Get-Process | Select Name,Handles | Sort Name

Ok, this is working quite good, but how does this works ?

Let’s use quick customs functions (Thanks to Laurent Dardenne for theses functions) to check this out !

Function Function1 {
  Begin { Write-Host "BEGIN Function 1" -f Green }
  Process {
    Write-Host "`tPROCESS Function 1" -F Yellow
    $_
  }
  End { Write-Host "END Function 1" -f Red }
}

Function Function2 {
  Begin { Write-Host "BEGIN Function 2" -f Green }
  Process {
    Write-Host "`tPROCESS Function 2" -F Yellow
    $_
  }
  End { Write-Host "END Function 2" -f Red }
}

Function Function3 {
  Begin { Write-Host "BEGIN Function 3" -f Green }
  Process {
    Write-Host "`tPROCESS Function 3" -F Yellow
    $_
  }
  End { Write-Host "END Function 3" -f Red }
}

#And execute this one liner


1..4 | Function1 | Function2 | Function3
pipeline

Pipeline execution workflow

The result is clear begin block is executed only once, the process block is executed each time, and the End is executed only once when all functions are already executed. So take care how you can’t your functions to handle pipes, because the execution order is different from what is writted in your script.

Interesting isn’t it ?

 

PowerShell 4.0+

Since PowerShell 4.0 you can bypass the pipe, but you can also stop using $_ variable. Properties are available directly with their names.

Get-Process | Where-Object Name –like “*a*”

Thanks PowerShell team product for this awesome stuff, but there is more again ! Now you don’t have to use pipe yet. Where-Object and Foreach-Object became methods of cmdlets used as an object !

Get-Process.Foreach({})
#or
Get-Process.Where({})

 

There are limits to that system, but it’s clearly a great idea, because don’t loose focus, in Powershell EVERYTHING is an object  and can be piped !

 

Ok, I hope you find this post usefull.

 

Regards