PowerShell: Customising the pipeline inputs

Sometime when using cmdlets there might be cases where you would assume two cmdlets would work together naturally and they just don’t. A good example of this is anything that takes -ComputerName as an input parameter (E.g test-connection) and the Get-ADComputer command.

In this example if you run Get-ADComputer -filter * you get a list of all computers in the current domain, say you now want to run Test-Connection to check machines are online, you might think you could just go:
Get-ADComputer -filter * | test-connection
Unfortunately you will be greeted with a wall of red text, this is because Get-ADComputer does not output an object with a ComputerName property, instead it has either Name or DNSHostName. You might now decide to output it all to a text file and ping them manually but your using PowerShell and there are easy ways do do this on the fly.

Method 1: Create a custom property on the ADComputer object with the name “ComputerName” so the next command receives what it expects:

Get-ADComputer -Filter * | 
   select @{n="ComputerName"; e={$_.DNSHostName}} | 

Method 2: Specify the name of the ADComputer object’s property in the next cmdlets input:

Get-ADComputer -Filter * | Test-Connection -ComputerName {$_.DNSHostName}

Using either of the above methods works with any cmdlet that accepts ComputerName as a pipeline input parameter.

Holy Trinity of PowerShell

The three most important cmdlets to remember in PowerShell, in fact the old ones you really need to remember are: Get-Command, Get-Help and Get-Member

Get-Command will give you a list of all installed cmdlets in PowerShell as well as their type, version and source. Additionally it has parameters for -verb or -noun so you can get a full list of all “Get-” cmdlets by typing: get-command -verb get or a list of all cmdlets that deal with services by typing: get-command -noun service

Get-Help is used once you know the command you are after, but you want to know more about how it works or what inputs or output to expect. You can provide some handy parameters to the get-help cmdlet such as -full to show the full help with examples, -showwindow to show the full help output in a searchable windows forms interface or -online to show the full detailed help on the technet website.

Get-Member is by far the cmdlet that I use the most, it gives you any methods and properties the current object in the pipeline has as well as specifying the type of the object your dealing with. This includes any properties that may not be visible by just outputting the object to the screen.

A notable gotcha for this is that if your passing get-member an array of strings (or any collection of any objects) it will give you the properties and methods of a string not an array. To determine if you are dealing with an array use the .gettype() .NET method.

PS C:\> $a = "Hello World"
PS C:\> $b = "hello", "world" 

PS C:\> $a | Get-Member
TypeName: System.String ..

PS C:\> $b | Get-Member
TypeName: System.String ...

PS C:\> $a.GetType() | select name, basetype
Name        BaseType 
String      System.Object

PS C:\> $b.GetType() | select name, basetype
Name        BaseType 
Object[]    System.Array