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:
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:
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:
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?
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
:
The same results are returned with only the last portion of the object type or the entire object type:
When I tested this against a function such as Get-NetAdapter
, specifying the entire object type
returned no results.
Specifying only the last portion after the last forward slash returned the expected results:
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
:
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.
µ