We have all used the Format-Table, Format-List, Format-Wide cmdlets to make our output more attractive. We know the importance of the Format- cmdlets now. But are we aware of the importance of the position of Format- cmdlets in the pipeline??
Have a look into the below three cmdlet examples:
Get-Process | Format-Table
Get-Process | Get-Member
Get-Process | Format-Table | Get-Member
When we do a Get-Member, why are we getting “Microsoft.PowerShell.Commands.Internal.Format.FormatStartData” or “Microsoft.PowerShell.Commands.Internal.Format.GroupStartData” instead of “System.Diagnostics.Process”, with just adding “Format-Table” in the pipeline.
The reason is that the Format-Table cmdlet does not output process objects. It consumes the process objects that you piped in and it outputs the formatting instructions – which is what the Get-Member sees and reports on.
Now try the below cmdlet:
Get-Service | select name, displayname, status | Format-Table | ConvertTo-Html | Out-File services.html
Open the services.html file with your favorite browser and you will be surprised to see the contents of that file, since it does not contain any of the service objects (which you were expecting). This is because you did not pipe the service objects to the ConvertTo-Html cmdlet, instead you have piped the formatting instructions.
This is the reason why the “Format-” cmdlets have to be the last thing on the pipeline.
One Object At A Time
We have to avoid putting multiple types of objects into the pipeline. This is because the pipeline is designed to handle only one type of objects.
Enter the cmdlets as below and run them, you will understand what I just said:
Get-Process; Get-Service
The semicolon allows me to put two cmdlets into the single command line, without having to pipe the output of the first cmdlet to the second one. In other words, both the cmdlets will run independently, however they will put the output to the same pipeline.
As you can see in the figure above, the output starts fine, displaying process objects. But the output breaks when displaying the service objects. Rather than producing a table for the service objects, PowerShell reverts to a list.
The formatting system looks at the first object in the pipeline and uses the type of that object to determine what formatting to produce. If the pipeline contains two or more kinds of objects, the output will not always be complete or useful.