May 11, 2014

PowerShell – Changing a command output’s default formatting

Chapter 10 – changing the default formats of a command’s output


You can find all my latest posts on medium.

Every time a command outputs a table of data, the output actually gets (invisibly) piped to the Out-Default command. This in turn pipes the data (invisibly)
to the defualt destination, which is, which by default is “out-host”, which is the terminal.

out-host formats the data into a tabular form using formating info contained in the following file:

(Note: DO NOT edit this file, becuase it is digitally signed. So powershell will stop working if you make the tiniest change)

It does this by looking up the xml file for the entry for the matching object (which you can find out using get-member)

All out-* commands uses the same xml file too (although write-host is an exception which is covered later).

However it is possible that a command outputs a table that does not have a pre-defined view in the xml file. In this case the out-* command
looks up a secondary xml file for formatting guidance:


If this also fails, the the out-* command will format the data based on this simple rule:
Display table if 4 or fewer properties, otherwise display data in list format.

There is also another out-* command called write-host, e.g.:

get-service | write-host

write-host also displays content to the terminal, but it does this by bypassing out-default, and hence bypassing out-host. As a result it
doesn’t make use of the xml formatting data.

Now with PS you can over-ride the default formatting system, with the help of a number of commands:

– format-table
– format-list
– format-wide

The format-table command has a number of parameters that are useful:

-autosize – with this, ps tries to adjust the widths to fill the column content, and leave minimal spacing either sides of the column.
This leads to a tighter layout.
-property – Lets you define which properties you want in the table (similar to select-object -property name1,name2,name3….)
-groupby – This breaks down a table, into smaller tables based on using a sensible property (e.g. status property for get-service command)
e.g. try:
get-service | sort-object -property status | format-table -groupby status
-wrap – PS may truncate some fields (indicated by “…”) to fit everything into the screen. Use the -wrap parameter to disable this suppression
and show everything on screen by wrapping around long objects to a new line.

This essentially shows a table of data in list format, a bit like a large number of mini-lists, one for each object (row). Also here is another way
(aside from the get-member command) to view all properties:

get-service | format-list * | select-object -first 3

This takes a property from an existing table, and then creates a new table with just the entries of this column. You can also specify how many
columns you want the table to be broken down into. e.g.:

get-service | format-wide -property status -column 10

Another thing you can do is change the names of the table’s default headers. This is done using the hashed table technique (like we did with select-object)

get-service | format-table -property @{name=’alias’; expression={$}},status,displayname

However when using hash tables with the format-* command, you can do some more custom formatting using some builtin hash parameters:

get-service | format-table -property @{name=’alias’; expression={$}; align=’left’;width=8},@{name=’status’; expression={$_.status}; align=’right’;width=8},displayname

Here we used the “align” and the “width” builtin parameters.

There is also the FormatString parameter, see here for info:

You can also do some simple maths with hash tables (when used in conjunction with format-* commands). For example if a column shows data in bytes,
and you want to change this to MB, then you can do:

get-process | format-table name,@{name=’VM(MB)’ ; expression={$_.VM / 1MB -as [int]}}

1MB is a special notation in PS for representing a megabyte.