[powershell] PowerShell: Format-Table without headers

In a PowerShell script, I have some objects that I pass to the Format-Table CmdLet.
The output of my script looks like this:

Something...

Operation AttributeName  AttributeValue
--------- -------------  --------------
Delete    Member         John Doe

Something else...

Since the meaning of the fields is pretty self-explanatory, I would like to remove the headers, the '---' separators and the blank lines at the beginning and at the end from the output of Format-Table.
I don't think that the CmdLet supports this (or at least if there's a parameter to do this I couldn't find it).

What would the best way to leave only the lines with the actual values from the output of Format-Table?

This question is related to powershell formatting

The answer is


I know it's 2 years late, but these answers helped me to formulate a filter function to output objects and trim the resulting strings. Since I have to format everything into a string in my final solution I went about things a little differently. Long-hand, my problem is very similar, and looks a bit like this

$verbosepreference="Continue"
write-verbose (ls | ft | out-string) # this generated too many blank lines

Here is my example:

ls | Out-Verbose # out-verbose formats the (pipelined) object(s) and then trims blanks

My Out-Verbose function looks like this:

filter Out-Verbose{
Param([parameter(valuefrompipeline=$true)][PSObject[]]$InputObject,
      [scriptblock]$script={write-verbose "$_"})
  Begin {
    $val=@()
  }
  Process {
    $val += $inputobject
  }
  End {
    $val | ft -autosize -wrap|out-string |%{$_.split("`r`n")} |?{$_.length} |%{$script.Invoke()}
  }
}

Note1: This solution will not scale to like millions of objects(it does not handle the pipeline serially)

Note2: You can still add a -noheaddings option. If you are wondering why I used a scriptblock here, that's to allow overloading like to send to disk-file or other output streams.


Another approach is to use ForEach-Object to project individual items to a string and then use the Out-String CmdLet to project the final results to a string or string array:

gci Microsoft.PowerShell.Core\Registry::HKEY_CLASSES_ROOT\CID | foreach { "CID Key {0}" -f $_.Name } | Out-String

#Result: One multi-line string equal to:
@"
CID Key HKEY_CLASSES_ROOT\CID\2a621c8a-7d4b-4d7b-ad60-a957fd70b0d0
CID Key HKEY_CLASSES_ROOT\CID\2ec6f5b2-8cdc-461e-9157-ffa84c11ba7d
CID Key HKEY_CLASSES_ROOT\CID\5da2ceaf-bc35-46e0-aabd-bd826023359b
CID Key HKEY_CLASSES_ROOT\CID\d13ad82e-d4fb-495f-9b78-01d2946e6426
"@

gci Microsoft.PowerShell.Core\Registry::HKEY_CLASSES_ROOT\CID | foreach { "CID Key {0}" -f $_.Name } | Out-String -Stream

#Result: An array of single line strings equal to:
@(
"CID Key HKEY_CLASSES_ROOT\CID\2a621c8a-7d4b-4d7b-ad60-a957fd70b0d0",
"CID Key HKEY_CLASSES_ROOT\CID\2ec6f5b2-8cdc-461e-9157-ffa84c11ba7d",
"CID Key HKEY_CLASSES_ROOT\CID\5da2ceaf-bc35-46e0-aabd-bd826023359b",
"CID Key HKEY_CLASSES_ROOT\CID\d13ad82e-d4fb-495f-9b78-01d2946e6426")

The benefit of this approach is that you can store the result to a variable and it will NOT have any empty lines.


The -HideTableHeaders parameter unfortunately still causes the empty lines to be printed (and table headers appearently are still considered for column width). The only way I know that could reliably work here would be to format the output yourself:

| % { '{0,10} {1,20} {2,20}' -f $_.Operation,$_.AttributeName,$_.AttributeValue }

Try -ExpandProperty. For example, I use this for sending the clean variable to Out-Gridview -PassThru , otherwise the variable has the header info stored. Note that these aren't great if you want to return more than one property.

An example:

Get-ADUser -filter * | select name -expandproperty name

Alternatively, you could do this:

(Get-ADUser -filter * ).name

Here is how I solve this. I just pipe the output to Out-String and then pass that output to the .NET Trim function:

(gci | ft -HideTableHeaders | Out-String).Trim()

This will strip out the line breaks before and after the table.

You can also use TrimStart to just take care of the header's line break if you still want the trailing line breaks.

(gci | ft -HideTableHeaders | Out-String).TrimStart()