Search code examples
powershelldatatableoutput

Why is outputting data with PowerShell as a table limited to 4 columns?


A snippet of my code:

$ipaddress = '127.0.0.1'
$port = 135,137,138,139,443,445   

for($i=0; $i -lt $port.length; $i++)
{

$out = new-object psobject

$out | add-member noteproperty Host $ipaddress
$out | add-member noteproperty Port $port[$i]
$out | add-member noteproperty Isopen $isopen[$i]
$out | add-member noteproperty Desc "Desc"
$out | add-member noteproperty Notes $Notes[$i]
$out | add-member noteproperty Issue $issue[$i]


Write-Output $out 

 }

What I'm trying to do is print out the results of my port scanner into a nice table. This works fine when there's 4 or less columns:

ss1

But Whenever I add more columns, even though there's space on the screen, it converts it into a list:

ss2

When I try to append "Format-Table" to it, it writes out the headers each time:

Write-Output $out | Format-Table

SS3

If I copy the line "Write-Output $out" outside the loop, it only prints out the last member. Any ideas on how to tackle this?


Solution

  • As you've found, PowerShell formats your output in a table by default, but opts for list view when the objects being formatted have more than 4 visible members.

    You can override this by explicitly invoking your preferred Format-* command. Simply "collect" all the output objects in an variable then explicitly pipe them to Format-Table:

    $ipaddress = '127.0.0.1'
    $port = 135,137,138,139,443,445   
    
    $objects = for($i=0; $i -lt $port.length; $i++)
    {
    
        $out = new-object psobject
    
        $out | add-member noteproperty Host $ipaddress
        $out | add-member noteproperty Port $port[$i]
        $out | add-member noteproperty Isopen $isopen[$i]
        $out | add-member noteproperty Desc "Desc"
        $out | add-member noteproperty Notes $Notes[$i]
        $out | add-member noteproperty Issue $issue[$i]
    
        Write-Output $out
    }
    
    $objects |Format-Table
    

    Unless you're running your code on PowerShell 2.0, I'd suggest using the 3.0 [pscustomobject] syntax for creating your object (and perhaps turn the whole thing into a function):

    function Get-PortStatus
    {
      param(
        [string]$IPAddress = '127.0.0.1',
        [intp[]]$Port = 135,137,138,139,443,445
      )
    
      # populate $isopen, $notes, $issue etc. here ...
    
      for($i=0; $i -lt $port.length; $i++)
      {
        # Write-Output is implied when the new object isn't assigned to anything
        [pscustomobject]@{
          Host   = $ipaddress
          Port   = $port[$i]
          IsOpen = $isopen[$i]
          Desc   = "Desc"
          Notes  = $Notes[$i]
          Issue  = $issue[$i]
        }
      }
    }
    

    Now you can do:

    PS C:\Users\Gabrielius> Get-PortStatus -IPAddress '10.0.0.10' -Port 80,443 |Format-Table