header image

What Formatting cmdlets do to your data

Posted by: | December 9, 2014 Comments Off on What Formatting cmdlets do to your data |

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
   indingException
    + 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

   TypeName: System.Diagnostics.Process

 

£> Get-Process | select name | Get-Member

   TypeName: Selected.System.Diagnostics.Process

 

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

   TypeName: System.Diagnostics.Process

 

You still have the original type.

 

However, lets look at formatting

£> Get-Process | Format-Table | Get-Member

TypeName: Microsoft.PowerShell.Commands.Internal.Format.FormatStartData

TypeName: Microsoft.PowerShell.Commands.Internal.Format.GroupStartData

TypeName: Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData

TypeName: Microsoft.PowerShell.Commands.Internal.Format.GroupEndData

TypeName: Microsoft.PowerShell.Commands.Internal.Format.FormatEndData

 

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.

under: PowerShell Basics

Comments are closed.

Categories