Formatting output in PowerShell

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:

  • Format-Custom
  • Format-Wide
  • Format-List
  • Format-Table

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:

  • Sort-Object
  • Select-Object

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.

psFormatting001

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

psFormatting002

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 *

psFormatting003

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

psFormatting004

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

psFormatting005

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

psFormatting006

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

psFormatting007

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

psFormatting008

Wow. That won’t do at all. Let’s try using Format-Wide instead:

Get-Service | Format-Wide DisplayName

psFormatting009

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

psFormatting010

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

psFormatting011

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?

psFormatting012

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.

First

Get-Service | Select-Object Name, Status, CanShutdown, CanStop -First 10

psFormatting013

By using the First parameter, we can choose to only select the first n items in the object

Last

Get-Service | Select-Object Name, Status, CanShutdown, CanStop -Last 10

psFormatting014

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!

NOTE!

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.

2 comments

  1. Thanks Stephane. This is a typical topic that I end up explaining to beginners, so I thought it would be easier to do a write-up and refer them to this blog-post when they are stuck 🙂

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s