Welcome PowerShell User! This recipe is just one of the hundreds of useful resources contained in the PowerShell Cookbook.

If you own the book already, login here to get free, online, searchable access to the entire book's content.

If not, the Windows PowerShell Cookbook is available at Amazon, or any of your other favourite book retailers. If you want to see what the PowerShell Cookbook has to offer, enjoy this free 90 page e-book sample: "The Windows PowerShell Interactive Shell".

3.2 Display the Properties of an Item as a Table

Problem

You have a set of items (for example, error records, directory items, or .NET objects), and you want to display summary information about them in a table format.

Solution

To display summary information about a set of items, pass those items to the Format-Table cmdlet. This is the default type of formatting for sets of items in PowerShell and provides several useful features.

To use PowerShell’s default formatting, pipe the output of a cmdlet (such as the Get-Process cmdlet) to the Format-Table cmdlet:

Get-Process | Format-Table

To display specific properties (such as Name and WorkingSet) in the table formatting, supply those property names as parameters to the Format-Table cmdlet:

Get-Process | Format-Table Name,WS

To instruct PowerShell to format the table in the most readable manner, supply the -Auto flag to the Format-Table cmdlet. PowerShell defines WS as an alias of the WorkingSet property for processes:

Get-Process | Format-Table Name,WS -Auto

To define a custom column definition (such as a process’s WorkingSet in megabytes), supply a custom formatting expression to the Format-Table cmdlet:

$fields = "Name",@{
    Label = "WS (MB)"; Expression = {$_.WS / 1mb}; Align = "Right"}
Get-Process | Format-Table $fields -Auto

Discussion

The Format-Table cmdlet is one of the four PowerShell formatting cmdlets. These cmdlets are Format-Table, Format-List, Format-Wide, and Format-Custom. The Format-Table cmdlet takes input and displays information about that input as a table. By default, PowerShell takes the list of properties to display from the *.format.ps1xml files in PowerShell’s installation directory. You can display all properties of the items if you type Format-Table *, although this is rarely a useful view.

The -Auto parameter to Format-Table is a helpful way to automatically format the table in the most readable way possible. It does come at a cost, however. To figure out the best table layout, PowerShell needs to examine each item in the incoming set of items. For small sets of items, this doesn’t make much difference, but for large sets (such as a recursive directory listing), it does. Without the -Auto parameter, the Format-Table cmdlet can display items as soon as it receives them. With the -Auto flag, the cmdlet displays results only after it receives all the input.

Perhaps the most interesting feature of the Format-Table cmdlet is illustrated by the last example: the ability to define completely custom table columns. You define a custom table column similarly to the way that you define a custom column list. Rather than specify an existing property of the items, you provide a hashtable. That hashtable includes up to three keys: the column’s label, a formatting expression, and alignment. The Format-Table cmdlet shows the label as the column header and uses your expression to generate data for that column. The label must be a string, the expression must be a script block, and the alignment must be either "Left", "Center", or "Right". In the expression script block, the $_ (or $PSItem) variable represents the current item being formatted.

Note

The Select-Object cmdlet supports a similar hashtable to add calculated properties, but uses Name (rather than Label) as the key to identify the property. After realizing how confusing this was, the PowerShell team updated both cmdlets to accept both Name and Label.

The expression shown in the last example takes the working set of the current item and divides it by 1 megabyte (1 MB).

One common stumbling block in PowerShell’s formatting cmdlets comes from putting them in the middle of a script or pipeline:

PS > Get-Process | Format-Table | Sort-Object Name
out-lineoutput : The object of type "Microsoft.PowerShell.Commands.Internal.
Format.FormatEntryData" is not valid or not in the correct sequence. This is
likely caused by a user-specified "format-*" command that is conflicting with
the default formatting.

Internally, PowerShell’s formatting commands generate a new type of object: Microsoft.PowerShell.Commands.Internal.Format.*. When these objects make it to the end of the pipeline, PowerShell then automatically sends them to an output cmdlet: by default, Out-Default. These Out-* cmdlets assume that the objects arrive in a certain order, so doing anything with the output of the formatting commands causes an error in the output system.

To resolve this problem, try to avoid calling the formatting cmdlets in the middle of a script or pipeline. When you do this, the output of your script no longer lends itself to the object-based manipulation so synonymous with PowerShell.

If you want to use the formatted output directly, send the output through the Out-String cmdlet as described in Recipe 1.24.

For more information about the Format-Table cmdlet, type Get-Help Format-Table. For more information about hashtables, see Recipe 7.13. For more information about script blocks, see Recipe 11.4.

See Also

Recipe 1.24, “Program: Search Formatted Output for a Pattern”

Recipe 7.13, “Create a Hashtable or Associative Array”

Recipe 11.4, “Write a Script Block”