The PowerShell Pipeline

One of the defining features of PowerShell is the object-oriented pipeline. The ability to “wire-up” parameters to the pipeline and allow objects (or properties) to be automatically assigned to them allows us to write code that is often variable-free.

By “variable-free”, I mean that instead of doing something like this:

$services=Get-Service *SQL* foreach($service in $services){ Stop-Service -Name $Service.Name }

we can write things like this:

Get-Service *SQL* | Stop-Service

There’s nothing wrong with the first script. It is logically laid out, it is clear what’s going on, and accomplishes the same goal. On the other hand, by introducing more variables (and more statements), we have added many more places where we can make mistakes.

When possible, you should write your functions so that they allow pipeline input wherever it makes sense.

When it doesn’t work

I was helping a co-worker with a script the other day and we found something unusual. The module he was using (open-source) allowed pipeline input, but it didn’t work quite right. The library (which dealt with processes running on specified computers) allowed you to pipe objects into the Stop function, but instead of using the objects as-is, it only used the PID from each object. The problem with that was that the Stop function then prompted for a computername for each object, although the incoming objects had properties which contained that value.

The solution was to hand-wire the pipeline like this:

Get-RemoteProcess <criteria> | foreach { Stop-RemoteProcess -ID $_.PID -ComputerName $_.ComputerName }

(note that these are not the actual function/parameter names…I’m not writing this to shame the original module author)

If the pipeline support had been implemented more reasonably, that could have been written like this:

Get-RemoteProcess <criteria> | Stop-RemoteProcess

As I said before, not supporting the pipeline (correctly) introduces places where we can make mistakes. And if you’re like me,

you will make mistakes in those places.

–Mike