Using PowerShell v3 Features to Figure Out the Mysterious PowerShell Pipeline

I actually wrote this blog a couple of weeks ago and postponed it until I could do further testing because I thought of some scenarios where it possibly wouldn’t work. I wrote a couple of new blogs over the past couple of weeks and forgot about this one. Low and behold, I had rescheduled this blog for today and forgot all about it so I had two blogs posted today!

I also have to say the PowerShell community is awesome! I had a PowerShell MVP send me a very courteous email that confirmed my previous thoughts. That this blog wasn’t really accurate so I decided to do a complete re-write and here it is:

There are two ways of connecting PowerShell commands together via the pipeline, one is "By Value" and the other is "By Property Name".

Initially, I thought I could use a new feature of PowerShell version 3, the ParameterType parameter of the Get-Command cmdlet to determine what cmdlets could accept pipeline input (I was wrong). What it can do is help you find what cmdlets accept that that type of input, although not necessarily by pipeline. It could be via pipeline input and/or via parenthesis after the parameter name depending on if that parameter actually accepts pipeline input By Value for that particular parameter.

Here’s the details of the ParameterType parameter of the Get-Command cmdlet:

gcm-paramtype0.png

To determine what PowerShell cmdlets can accept input from the Get-VM cmdlet that's part of the Hyper-V Module, start out by piping Get-VM to Get-Member as shown in the following example to determine what type of object Get-VM produces:

gcm-paramtype1.png

The Get-VM cmdlet produces a Microsoft.HyperV.PowerShell.VirtualMachine object which is commonly referred to as the last portion of the name after the last dot. In the previous example, it would be called a VirtualMachine object.

Now we'll run the Get-Command cmdlet specifying the ParameterType parameter and use the object type name that we previously determined that Get-VM produced as the value for the ParameterType parameter as shown in the following example:

gcm-paramtype2.png

This returned a list of cmdlets that can each accept input from the Get-VM cmdlet. A subset of the returned results are shown in the previous image. A total of 82 cmdlets were returned on my Windows 8 machine that has the Hyper-V PowerShell module installed. That's a lot of cmdlets that can accept input from the Get-VM cmdlet. Try figuring that out manually, but if you're using PowerShell, why would you want to do anything manually?

gcm-paramtype3.png

One thing I found during my testing, is you can specify the last portion of the object type as shown in this example of piping Get-Process to Get-Member:

gcm-paramtype4.png

The same results are returned with only the last portion of the object type or the entire object type:

gcm-paramtype5.png

When I tested this against a function such as Get-NetAdapter, specifying the entire object type returned no results.

gcm-paramtype6.png

Specifying only the last portion after the last forward slash returned the expected results:

gcm-paramtype7.png

That's neat and all, but can't I accomplish all of this in a one-liner instead of having to pipe a cmdlet to Get-Member and then run a second command to figure out what cmdlets accept the output of the first cmdlet as their input? Sure, as a matter of fact, this exact example is #14 in the help for Get-Command:

gcm-paramtype8.png

The ParameterType parameter along with the ParameterName parameter of the Get-Command cmdlet are some of the best hidden and most underrated features in PowerShell version 3.

µ