The Scripting Pipeline

Save the script writing for when it's needed -- PowerShell allows stringing together of cmdlets to perform useful work.

By Don Jones

09/26/2006

If you remember a few months ago, I covered scripting with Powershell (see "Shrinking Scripts," May 2006). A nifty feature of PowerShell is the capability to use cmdlets, stringing them together -- look, ma, no script writing needed -- to perform useful work. The key is PowerShell’s pipelines, which aren’t at all unlike the piping you could do under the Cmd shell. It basically works like this:

Command1 | command2 | command3

Command1 runs, and its output is "piped" to Command2, which uses that input to do whatever it’s going to do and sends its output to Command3… ... and so forth. The trick with PowerShell is that cmdlets don’t output text, but rather entire objects (some of which might just be string objects containing text, of course). For example, if you run the Get-Process cmdlet, you’ll get a nice text listing of processes, but that’s just because PowerShell is doing some translating for you. What you’re really getting is a collection of Process objects -- PowerShell just knows you want something human-readable, and so it takes the most popular properties of the objects and formats a nice table for you.

You could pipe those objects directly to another cmdlet, though. Don’t try this at home (it’ll blue screen your computer), but here’s a simple example:

Get-Process | Stop-Process

That will take the list of all running processes and pipe them to the Stop-Process cmdlet which will, um, stop them. Hence the blue screen I mentioned earlier. But this is also a good time to point out how you can figure all this out on your own. The first step is to know what output any cmdlet is actually creating, regardless of any fancy formatting PowerShell might be doing:

Get-Process | Get-Member

Get-Member tells you what kind of object something is; in this case, it’s a System.Diagnostics.Process. Cool. If you run Help Stop-Process you’ll see three versions of its usage: One accepts an Int32 as its first parameter, which is named -Id, suggesting that it wants a process ID to stop. The second usage has the first parameter -Name, which is a string -- the name of the process you want to stop. The third usage has -InputObject as the first parameter, and it’s a System.Diagnostivcs.Process -- where did we see that before?

So when you run Stop-Process, it looks at the data type of the first parameter to figure out if you’re specifying a process ID, a process name or passing an actual process. When you pipe the output of Get-Process -- which, we’ve determined, is outputting a System.Diagnostics.Process object -- the Stop-Process cmdlet recognizes the data type and runs with the third usage example.

Don Jones is a multiple-year recipient of Microsoft’s MVP Award, and is an Author/Evangelist for video training company Pluralsight. Don is also a co-founder and President of PowerShell.org, a community dedicated to Microsoft’s Windows PowerShell technology. Don has more than two decades of experience in the IT industry, and specializes in the Microsoft business technology platform. He’s the author of more than 50 technology books, an accomplished IT journalist, and a sought-after speaker and instructor at conferences worldwide. Reach Don on Twitter at @concentratedDon, or on Facebook at Facebook.com/ConcentratedDon.