Search notes:

PowerShell cmdLet Format-Table

Render property-values in table

The format-table cmdLet pivotizes the property-values of the objects that are pipelined into this cmdLet. That is, the values of one object are displayed in the same row rather than each separately on its own line.
For example, the output of get-host might be:
PS C:\> get-host


Name             : ConsoleHost
Version          : 5.1.17763.134
InstanceId       : c5b6e84b-4f84-4b83-8521-f49a41517b1c
UI               : System.Management.Automation.Internal.Host.InternalHostUserInterface
CurrentCulture   : en-US
CurrentUICulture : en-US
PrivateData      : Microsoft.PowerShell.ConsoleHost+ConsoleColorProxy
DebuggerEnabled  : True
IsRunspacePushed : False
Runspace         : System.Management.Automation.Runspaces.LocalRunspace
However, if pipelined through format-table, it becomes:
PS C:\Users\Rene\github\temp\PowerShell\cmdLets\format-table> get-host | format-table

Name        Version       InstanceId                           UI                                                                   CurrentCulture CurrentUICulture
----        -------       ----------                           --                                                                   -------------- ----------------
ConsoleHost 5.1.17763.134 c5b6e84b-4f84-4b83-8521-f49a41517b1c System.Management.Automation.Internal.Host.InternalHostUserInterface en-US          en-US

-autoSize

With the parameter -autoSize in force, format-table «prints» the property values according to their size (length) so that the values are not truncated anymore.
Without -autoSize, the values are possibly truncated so that they fit the view in which format-table operates.

Types involved

The format-table cmdLet involves quite a few types to achieve the desired formatting, which I try to demonstrate with the following snippets.
First, I assign the result of get-process to a variable. Thus, I am sure that I have a stable set of objects:
PS C:\> $procs = get-process
I then pipe the objects that are stored in $procs through format-table and assign the result to another variable:
PS C:\> $formatted = $procs | format-table
I count the number of objects in both variables. Since both variables are actually arrays, I can use the length property:
PS C:\> $procs.length
483
PS C:\> $formatted.length
487
It turns out that the format-table returns 4 objects more than was piped into it. It seems a reasonable assumption that the additional objects are added at the beginning and/or end. Let's investigate:
The first object:
PS C:\> $formatted[0].GetType().FullName
Microsoft.PowerShell.Commands.Internal.Format.FormatStartData
The second object
PS C:\> $formatted[1].GetType().FullName
Microsoft.PowerShell.Commands.Internal.Format.GroupStartData
The third object
PS C:\> $formatted[2].GetType().FullName
Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData
The second last object
PS C:\> $formatted[-2].GetType().FullName
Microsoft.PowerShell.Commands.Internal.Format.GroupEndData
And the last object
PS C:\> $formatted[-1].GetType().FullName
Microsoft.PowerShell.Commands.Internal.Format.FormatEndData

Implicit invocation of Format-Table by Out-Default

The Out-Default cmdlet, into which all objects produced in a pipeline are eventually piped, might decide to implicitly use Format-Table internally to render objects.
A typical kind of objects for which Out-Default renders with Format-Table are custom objects with up to four properties and without a defined custom formatting.
Such objects are created, for example, by selecting less than five properties with Select-Object. Thus, the output of the following pipeline is rendered using Format-Table:
get-childItem | select-object name, length, isReadOnly, creationTime

300 Millisecond delay when implicitly invoked

When Format-Table is (implicitly?) invoked, there is a period of 300 milliseconds in which the command collects objects in order to determine the width's of the columns.
The longest width encountered during this period is then taken as width for the columns. Column values that exceed these widths are truncated.
This behavior is demonstrated with the following PowerShell script:
param (
   $milliSeconds
)

$ticks_ = (get-date).ticks

$i = 0
while ( (get-date).ticks - $ticks_ -lt $milliSeconds * [System.TimeSpan]::TicksPerMillisecond ) {
   $i++
   [pscustomobject] @{num = $i; txt = 'abcdefghi' }

   start-sleep -milliSecond 50

}

$i++; [pscustomobject] @{num = $i; txt = 'abcdefghijklmnopqrstuvwxyz' }
$i++; [pscustomobject] @{num = $i; txt = 'abcdef'                     }
Github repository about-PowerShell, path: /cmdlets/table/format/generate-objects-for-x-ms.ps1
The script has one parameter which roughly specifies the duration after which the first «long» value for txt is produced.
Calling the script with 250 milliseconds produces:
PS> .\generate-objects-for-x-ms.ps1 250

num txt
--- ---
  1 abcdefghi
  2 abcdefghi
  3 abcdefghi
  4 abcdefghi
  5 abcdefghi
  6 abcdefghijklmnopqrstuvwxyz
  7 abcdef
With more than 300 milliseconds, the output of txt becomes truncated:
PS> .\generate-objects-for-x-ms.ps1 350

num txt
--- ---
  1 abcdefghi
  2 abcdefghi
  3 abcdefghi
  4 abcdefghi
  5 abcdefghi
  6 abcdefghi
  7 abcdef...
  8 abcdef
If Format-Table is invoked with the option -AutoSize, the command will collect all objects before writing them to the console, thus, with -AutoSize, there is no truncating taking place.
However, there is no immediate output for each object received by the command, as demonstrated with the two following commands:
PS> .\generate-objects-for-x-ms.ps1 3000 | format-table             # Continous but truncated output
PS> .\generate-objects-for-x-ms.ps1 3000 | format-table -autoSize   # No trunctaion, but need to wait for script to be finished until first output appears.

See also

PowerShell command verb: format
The opposite of format-table is format-list.
Powershell command noun: table
The .NET namespace Microsoft.PowerShell.Commands.Internal.Format.

Index