This post will go through how to format output for the screen in PowerShell, and is mainly aimed at beginners will little to no experience. Read on to learn how you can control how data is shown in the console!
As you might already know, PowerShell outputs objects, but at first it might seems that the output format is kind of random. Sometimes the data is formatted as a list, and sometimes as a table. Fear not, there is method to the madness!
Before we go into that though, let’s take a look at the different means we have at our disposal to influence data output. PowerShell comes with four cmdlets for formatting output:
By piping data into these, we can control how the output looks in the console. In addition to these, the following cmdlets can also come in handy to shape the output to your needs:
The reason the output might seem a bit random or chaotic whether it’s shown as a table or a list, is because usually, if the number of properties in the default view is four or less, it will be shown as a table, while if it’s more than four it will be shown as a list. This is all to do with screen real estate, but using the Format-cmdlets we can override this behaviour.
Before we start, let’s see the default output of Get-Service, the command we will use in all the examples.
Format-List (alias: fl)
By using the Format-List cmdlet we can force the output to be shown as a list. In it’s simplest form it can be used like this:
Get-Service | Format-List
This will force the output of the Get-Service cmdlet to show its output as a list. If a default list view exists for the data type, it might very well be that just some of the properties are shown. The be sure you are getting all properties, you can use a wildcard to specify that you want to show all properties, like this:
Get-Service | Format-List *
This will force the output of the Get-Service cmdlet to show all available properties as a list.
You can also specify the names of the properties you want to show:
Get-Service | Format-List Name,DisplayName,ServiceType
This will show only the Name, DisplayName and ServiceType properties as a list.
Format-Table (alias: ft)
By using Format-Table instead of Format-List we are instead forcing the output to show as a table instead. Format-Table supports largely the same parameters as Format-List, so we can change the previous examples into showing a table layout instead:
Get-Service | Format-Table Get-Service | Format-Table * Get-Service | Format-Table Name,DisplayName,ServiceType
Using the wildcard ‘*’ with Format-Table is not something I recommend for objects with lots of properties though, as its largely impossible to see anything meaningful on the screen, thought it can be made slightly better by using the Wrap parameter; though not by much.
Format-Table have one extra property that is worth mention though, the AutoSize parameter. By using this the table will set the column size of the table based on the width of the data in the visible properties. This is probably easier to see for your self. Consider the following command:
Get-Service | Format-Table Name,CanShutdown,CanShutdown
As you see, by default the use of the screen might not optimal for this output, but let’s use AutoSize and see where that gets us:
Get-Service | Format-Table Name,CanShutdown,CanShutdown -AutoSize
Now you see that the columns are not stretched across the full width of the screen, and it often makes the output easier to read on the screen.
Format-Wide (alias: fw)
If you want to show only one property of a large object, using Format-Table or Format-List means you have to do a lot of scrolling if you are looking for something specific. A better choice it that scenario can be to use Format-Wide. This cmdlet will take one property and present it in a two-column view.
First lets start by using format-List, but only show one property:
Get-Service | Format-Wide DisplayName
Wow. That won’t do at all. Let’s try using Format-Wide instead:
Get-Service | Format-Wide DisplayName
That is a lot easier to read, don’t you think?
Format-Custom (alias: fc)
This cmdlet is the least useful of the format cmdlets. It uses a customized view to format the output, so you will either have to create a view yourself, or use a view already defined by other cmdlets/modules. As this post is targeted to beginners, I will not go into detail of Format-Custom, other than to mention that it exists.
Sort-Object (alias: sort)
Usually the output of an object is sorted by the first property, or by a property defined in the default view for the object type, but by using the Sort-Object cmdlet you can override this to sort on any property:
Get-Service | Sort-Object Status
By using the Descending parameter, you can reverse the default sorting order. Another useful parameter Sort-Object supports are the Unique parameter. Using this means it will not show any duplicates of the values in the property you are sorting on.
Get-Service | Sort-Object Status -Unique
As you see, it only lists unique values for the Status property – not very useful in this example though.
Select-Object (alias: select)
In previous examples you have seen that we can choose which properties we want to display on the screen when using the Format-* cmdlets. On the surface of it, this next command seem to do the same thing. But what Select-Object is actually doing, is selecting a subset of the object.
Let’s see some examples of it in use:
Get-Service | Select-Object Name, Status, CanShutdown, CanStop
You can probably guess what this command does, right?
You could just as easily have achieved the same thing using the Format-Table command, but with one very important difference. While using the Format-* cmdlets transform the objects, Select-Object retains the object structure. This means that you can further pipe the results down the pipeline for additional processing. It also supports some additional handy parameters.
Get-Service | Select-Object Name, Status, CanShutdown, CanStop -First 10
By using the First parameter, we can choose to only select the first n items in the object
Get-Service | Select-Object Name, Status, CanShutdown, CanStop -Last 10
Using the Last parameter will, not surprisingly, show you the last n items instead.
Select-Object have additional parameters that might come in handy, but I challenge you to look up the help information of Select-Object to figure these out for your self.
That actually goes for all of the cmdlets I have discussed. Take some minutes to read the built-in help information, as well as the provided examples, to learn more about them. Getting used to looking up help is a key concept in getting better at PowerShell!
I have briefly mentioned it above, but I’ll mention it again, as this is an easy mistake to make as a PowerShell beginner. When you use the Format-* cmdlets together with objects, you “break” the objects. What I mean by this is that after the format commands have done their thing, the data is only usable to show on the screen. Something that I have seen often done wrong, is someone using Format-Table to filter the information they want, and then pipe the results to Export-Csv because they want to send the results to they boss. This will not work! So remember, if you want to use the Format-* cmdlets in a pipeline, they should always come as the last item in the pipeline!
I hope this post have been instructional. Please drop me a comment if you have further questions, or if you spot some mistakes I might have made.