Windows PowerShell Tutorial 7 - Formatting Output

Windows PowerShell Tutorial 7 - Formatting Output

By default nearly all of cmdlets in PowerShell display data in a table format.

Example of Table Format


The cmdlet Get-Process by default displays data in a Table Format

As the default display is so common, and often sufficient for the User to get the information they are after in an easy to read format, many people are not aware that PowerShell actually has four Format cmdlets to choose from:
  • Format-Table
  • Format-List
  • Format-Wide
  • Format-Custom
Given, Format-Table is the default result of most cmdlets, you rarely need to specify this if you are piping information. However, you will need to specify the other three choices. So how precisely does one specify a Format?

Well because the four Format options are cmdlets, you can simply pipe information to the cmdlet to produce the result you want. Compare the following two images to see why changing the default behaviour of the Get-Service cmdlet can actually be easier to read.


Notice too
that the Format-List option provided additional information without the need to add additional conditions to the initial command, where as the default Table-Format for the cmdlet Get-Service only provides three columns of information.

Another thing to notice with the default Table-Format behaviour of the Get-Service cmdlet is that the columns are squashed and some text as a result is truncated, which is why you see the ... appear on some lines.

This is where the option to pipe information to the Format-Wide cmdlet can come in handy. Take a look at what happens when you pipe Get-Service to Format-Wide:


The names of the services are now displayed in two columns the columns are further apart, making it possible to read the entire name, without the ... appearing.

Something else worth noting is you can explicitly state how many columns to display using the parameter -Column and using an integer as the value passed through the parameter.


Applying the parameter -Column and the integer value 4 changes the default 2 columns to 4. However, this reintroduces the ... for some of the Service names as a result.

Earlier we saw what happened when you chose to pipe Get-Service to Format-List, but take a look how it can actually be easier to find something quickly, if we then add the parameter -GroupBy and name as its value.


Granted the Name is already in the listed data, but I personally find it easier when using -GroupBy name to help more clearly break down what can be a long list of information into their own groups.

What if you want to get specific columns of data, and not just the standard results?

Take a look at what happens when we apply the parameter -Property with three arguments, then add an additional parameter -Autosize, to the Cmdlet Get-Process:


The parameter -Autosize helps ensure all data fits to screen, but this to some degree is determined by how many columns there will be, and also the data in each column, so in some cases data will need to be truncated with the ...

Note too, while Get-Process by default displays a result in Table format when you pipe its result so as to include additional parameters, you must declare the Format-Table cmdlet if that is what you wish to see.

In this case you can see its useful information but it'd definitely be easier to read in a Format-List style:


There are a handful of other arguments you can use for formatting, but rather than explain each and everyone of them, simply use your Windows PowerShell ISE and as you type the intellisense will offer you a list of choices. Experiment with them, and see which result you take a liking to. Just note, some of the choices can only work with particular data types, so if you choose an option that does not match this, you will get a warning about this and more than likely see a red squiggly line appear to prompt you something is wrong and needs your attention.

That leaves us with the fourth option: Format-Custom.

You as the programmer find a particular format you prefer, and want to make repeated use of this format, without the hassle of having to type in all your arguments, conditions, etcetera each time. What do you to? Well that is where Format-Custom comes into play.

The Format-Custom cmdlet formats the output of a command as defined in an alternate view. Format-Custom is designed to display views that are not just tables or just lists. You can use the views defined in the *format.PS1XML files in the Windows PowerShell directory, or you can create your own views in new PS1XML files and use the Update-FormatData cmdlet to add them to Windows PowerShell.

The Format-Custom cmdlet has a number of parameters you can use to create an alternate view. Here is a list of those parameters:
  • -Property which takes any Object <Object[]> as a value
  • -Depth which takes any Integer <Int32> as a value
  • -DisplayError which forces an error message to be displayed to command line
  • -Expand which takes any String <String> as a value
  • -Force which forces all content of an error be displayed at the command line
  • -GroupBy which takes any Object <Object> as a value
  • -InputObject which takes any Object and pipes it via the System.Management.Automation.PSObject <PSObject>
  • -ShowError which shows an error
  • -View which takes any String <String> as a value
  • <CommonParameters> which is a set of parameters that can be used with all cmdlets in PowerShell. For more information about that see the following:
The -Property parameter is used to explicitly specify the Object properties that you want to appear in the display, and also the order in which they appear. You are also able to use Wildcards if you wish.

Note: This parameter is optional (i.e. you do not have to use it). If you do use it though, then note you cannot use both -Property and -View in the same command.

Also note: You can use a newly calculated property as the value. To do this you will need to create a Hash Table which has two valid keys:

  • Expression <String> or <Script block>
  • Depth <Int32>
The -Depth parameter is used to explicitly specify the number of columns in the display. It takes an positive Integer for its value. Again, this is an optional parameter, so you do not have to use it if you do not wish to.

The -DisplayError parameter instructs the computer to display any error message to the Command line. This too is an optional parameter. Typically it is not used, except for when the programmer is attempting to debug their Code block when things do not go as intended.

To demonstrate what you could see if using this parameter, lets purposely run an expression that is doomed to fail:


The -Expand parameter is also optional. This parameter is used to explicitly specify
that this cmdlet formats the collection object, as well as the objects in the collection.

This parameter is designed to format objects that support the ICollection (System.Collections) interface. The default value is EnumOnly.

The values that can be used with this parameter are:

  • EnumOnly which displays the properties of the objects in the collection.
  • CoreOnly which displays the properties of the collection object.
  • EnumOnly & CoreOnly which will display the properties of the collection object and the properties of objects in the collection.
The -Force parameter is used to overcome the default behaviour of the parameters -ShowError and -DisplayError, which both may only display part of an error message. If you use -Force in tandem with these two parameters it forces the entire error message to be displayed at the command line, no matter how long that error message is. Again, this would more typically be used as a debugging measure, and is an optional parameter as a result.

The -GroupBy parameter you will already be familiar with as I've explained this earlier in the tutorial. To remind you though, this parameter allows you to format a cmdlets output into groups based on a shared property or value. You can alse enter an expression or a property of the output.

This value of this parameter can also be a new calculated property.

To create a calculated, property, use a hash table, using the following valid keys:
  • Name (or Label) <string>
  • Expression <string> or <script block>
  • FormatString <string>
The -InputObject parameter allows you to explicitly specify the Object you wish to be formatted with your Custom style. You can input this in one of two ways:
  1. You can enter a variable which contains the Object(s) you want to format, or
  2. You can enter an expression or a command to get the Object to format.
The -ShowError is a option parameter mostly used for debugging. I already demonstrated its usefulness in the previous illustration. If you use this parameter you are basically ensured error the Cmdlet being actioned produces is able to be passed through the pipe. You may recall in a previous tutorial I mentioned that pipes can block error messages.

The -View parameter is used to allow you to format an object using a specific Format-Custom style you created. If you do not use this parameter then the default style built-in to PowerShell will be used instead. A reminder too, that you cannot use -View in tandem with -Property in a command!

Some Final Notes:

Inputs for the Format-Custom makes use of the built-in System.Management.Automation.PSObject which allows any Object to be piped to the cmdlet Format-Custom..

Outputs for the Format-Custom makes use of the built-in Microsoft.PowerShell.Commands.Internal.Format which allows Format-Custom to return the formatted objects for display.

As Format-Custom is designed to display alternate views to ordinary Tables or Lists, if you wish to display an alternate table view, use Format-Table, and if you wish to display an alternate list view, use Format-List.

If typing Format-Custom gets tiring, use its alias which is FC or fc.

If you are using the -GroupBy parameter this assumes the Object(s) are already sorted. To prevent issues arising, before using Format-Custom to group objects, use the cmdlet Sort-Object.

Well that concludes this tutorial. Hopefully, you found it useful.

I have not decided what topic to cover next in this series of Tutorials, and will not be adding any new tutorials in the immediate future, owing to time restraints. If you have a topic you want covered, be it a basic one, or a more advanced one, let me know.


  • Like
Reactions: Ian

First release
Last update

More resources from Regedit32