Formatting Output

Formatting output from cmdlets doesn’t have to be complicated. PowerShell ships with cmdlets that can take the output from other cmdlets and display the information in a pretty way. Format-Custom, Format-List, Format-Table, and Format-Wide are the ways to present data at the console.

Out-Default

Out-Default is a cmdlet you likely have never heard of but rely on whenever you spit an object to the console. Out-Default is the cmdlet that figures out which way to format the information you have piped out. Try this example to see what I mean.

Get-Process -Name powershell | 
    Select-Object Handles,Name,ID,CPU

The console should return a table with headers of Handles, Name, ID and CPU utilization and a row for each powershell.exe process you have open. Seems simple right? Now add Working Set memory (WS) as one of the properties you want returned to the console and run the following:

Get-Process -Name powershell | 
    Select-Object Handles,Name,ID,CPU,WS

Odd, we no longer get a table, we get a list. It is almost as if we changed the pipeline from Format-Table to Format-List. This is what Out-Default does in the background for you. It knows that four headers in a table will display fine most of the time in the console window but five columns of information is pushing it. With five columns Out-Default now formats the output using lists. Out-Default, while invisible, is formatting the console output for you.

Expressions

If you’d like to see the values displayed with different property names or as calculated fields you have use expressions to accomplish the task.

In this example I want the process name to show as ProcessName and the working set memory to be named RAM and have it be expressed in Megabytes. *Note: Carriage returns after the pipeline character will continue the pipeline onto the next line. This is used to improve the readability of your code. *

Get-Process -Name powershell* | 
    Format-List -Property @{
        Label="ProcessName";Expression={$_.Name}
    },
    @{
        Label="RAM";Expression={ $_.WorkingSet / 1MB -as [int] }
    }

We used the Property argument in Format-List to return our custom output. The syntax used is a hash table containing Label and Expression keys. The value should be a string and an expression should be a script block. This same syntax works for Select-Object as well.

Custom Format Files

You may wonder how Out-Default is smart enough to chose which properties to show and which to hide. The answer is, it isn’t smart enough. The developer of the cmdlet chooses what to show and what not to. If we poke around in the module manifest of the Microsoft.PowerShell.Diagnostics module at “C:\windows\System32\WindowsPowerShell\v1.0\Modules\Microsoft.PowerShell.Diagnostics\Microsoft.PowerShell.Diagnostics.psd1” you can see the FormatsToProcess field and two format.ps1xml files. Those two files dictate how the object information is shown.

Gotchas

Something to keep in mind. The Format cmdlets change the object type in the pipeline. That means if you were piping process objects into Format-List you no longer get process objects out. If we pipe the output of one of the format cmdlets into Get-Member we find that we get objects of type Microsoft.PowerShell.Commands.Internal.Format.FormatEndData. Hardly anything we can work with.

As a rule of thumb, the Format cmdlets should be the last thing on the pipeline, unless you are using an Out cmdlet after. Out-Printer will print your formatted objects without issue.