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:emp | 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:emp
Exporting Data: Get-ChildItem C:emp | 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:emp | 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.