How can I store output from Format-Table for later use

Solution 1:

Problem with Format-cmdlets

The issue here is your use of FT which is an alias for Format-Table. These Format- cmdlets are designed for console/screen output only. There are many things you can do with them to tailor that output but in every case PowerShell needs to massage the data in order to be able to do so. This includes breaking down to the passed objects into groups of different objects...

Microsoft.PowerShell.Commands.Internal.Format.FormatEndData
Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData
Microsoft.PowerShell.Commands.Internal.Format.FormatStartData
Microsoft.PowerShell.Commands.Internal.Format.GroupEndData
Microsoft.PowerShell.Commands.Internal.Format.GroupStartData

The above data types were extract from running this code.

Get-ChildItem c:\temp | Format-Table | Get-Member

So you no longer have the System.IO.FileInfo and System.IO.DirectoryInfo objects that you would normally get from Get-ChildItem

Another large issue comes from Format-cmdlets nature to truncated data, like arrays with a large numbers of elements or long strings, to make as much fit on screen. In the case of arrays, this is due to the preference variable $FormatEnumerationLimit which is commonly defaulted to 4.

Ten Numbers                                                                                                                                                  
-----------                                                                                                                                                  
{1, 2, 3, 4...}  

These, and other, limitations can all be mitigated with cmdlet switches like -AutoSize and -HideTableHeaders, out-string -width, etc. That does not matter however because...


Solution

Good news is the solution is very simple. Stop using them for anything other than console output. Using my earlier example:

  • Saving results in a variable?: $result = Get-ChildItem C:\temp

  • Exporting Data: Get-ChildItem C:\temp | Export-CSV $path -NoTypeInformation. Other Export-cmdlets could be preferred here like Export-CLIXml for complex objects when you want to store them for use elsewhere. If you are just looking for something pretty to include in your output then consider ConvertTo-HTML instead.

  • Extracting individual properties?: Just use Select-Object. $result | Select prop1, prop2. You can also expand your property selection to just get the strings or string array with -ExpandProperty: $result | Select -ExpandProperty prop1

  • Performing inline calculations with said properties?: Use calculated expression just as you would with the Format-Cmdlets. $result | Select prop1, @{Name="prop2";Expression={$_.prop2 * 3}


Potential Acceptable Use

Some prefer the output for use in emails and for recording statistics. While it is integral to keep data in its more easily used format for later use. However if you really need that data keep in mind that you are not working with the object your originally had anymore.

So if you needed your data in a table format but stored as a string then consider Out-String

$body = Get-ChildItem c:\temp | Format-Table | Out-String

but remember that Format-Table will play with object output in order to get it to display on screen (truncated array properties and long strings). Really.. if you wanted it nice and formatted then you should just use ConvertTo-HTML.

Point is you almost never need to keep the data from Format-Table. There is almost always a better way.