I have seen an increasing number of questions recently where the answer has been to remove Format-Table from the pipeline. As an example consider the names of the processes running on your machine
Get-Process -Name calc | Stop-Process
works because you are piping the selected object into the Stop-Process cmdlet.
Now think about this
Get-Process -Name calc | select Name | Stop-Process
a bit more long winded (the select isn’t necessary) but the resultant object hitting Stop-Process identifies a process by name which is all Stop-Process needs to work.
As a way to approach the reason for the first sentence in the post is there any difference between these two statements?
Get-Process -Name calc
Get-Process -Name calc | Format-Table
The output to screen looks identical. So I should be able to do this:
Get-Process -Name calc | Format-Table | Stop-Process
What I get is a bunch of errors of the form:
Stop-Process : The input object cannot be bound to any parameters for the command either because the command does not take pipeline input or the input and its properties do not match any of the parameters that take pipeline input.
At line:1 char:41
+ Get-Process -Name calc | Format-Table | Stop-Process
+ CategoryInfo : InvalidArgument: (Microsoft.Power…FormatStartData:PSObject) [Stop-Process], ParameterB
+ FullyQualifiedErrorId : InputObjectNotBound,Microsoft.PowerShell.Commands.StopProcessCommand
The reason for this is simple. The Format cmdlets destroy your pipeline and objects. They take what they are given and output formatting directives. The only thing you can do with them is display them on screen (you can pipe to a text file but effectively the same thing)
If in doubt about what you’re dealing with at any time use Get-member
£> Get-Process | Get-Member
£> Get-Process | select name | Get-Member
Notice the slight change in that its now Selected.System.Diagnostics.Process instead of System.Diagnostics.Process
This only applies if you’re selecting a subset of properties. If you want the first N objects
£> Get-Process | select -First 5 | Get-Member
You still have the original type.
However, lets look at formatting
£> Get-Process | Format-Table | Get-Member
You get 5 different objects out – none of which have anything to do with your processes – apart from the values.
The Format cmdlets are designed to format your data for display. Thats all they do. Once your data hits the Format cmdlets that data can only be used fro display – nothing else. Put your Format cmdlets at the end of your pipeline and don’t attempt to do anything else with the data.