6

I'm writing a script emitting output in columns using Format-Table, and cannot get more than 9 to show (either with or without the -AutoSize argument).

Just in case it is not my fault, just something undocumented:

What's the maximum number of columns which Format-Table can show?

If it is unbound, I'll distill a small reproducible case from my script.

I'm using PowerShell 4.0, and create the objects to list like this:

    New-Object PSCustomObject -Property ([Ordered] @{
        "BDS #" = $bdsVersion
        "HKCU" = $hkcuBasePath
        "HKLM" = $hklmBasePath
        "Name" = $fullName
        "CompilerVersion" = $compilerVersion
        "RTLVersion" = $rtlVersion
        "Define" = $define
        "Characterset" = $characterSet
        "Architectures" = $architecture
        "Frameworks" = $framework
        "DllSuffix" = $dllSuffix
    })

The DllSuffix column doesn't show even though my console window is wide enough (300 characters wide).

Edit:

As per suggestion by Cole9350, I added the -Wrap to the -AutoSize argument to format the table, but it still fails:

function Get-BDS-ProductSummaries {
    $bdsVersions = Get-BDS-Versions
    $bdsVersions | ForEach-Object { 
        $summary = Get-BDS-ProductSummary $_
        $summary
    } | Format-Table -AutoSize -Wrap
    # http://blogs.technet.com/b/nexthop/archive/2011/03/21/psformatorselect.aspx
    Write-Host "Slash separated values like xxx/yyy means native/.NET"
}

I call this function from my "main" portion of the script:

$args | ForEach-Object {
    $arg = $_
    switch ($arg) {
# ...
        'ProductSummaries' {
            Write-Host "Product Summaries:"
            Get-BDS-ProductSummaries
        }
# ...
    }
    $anyArg = $True
}

The link explaining about combining -Wrap with -Format-Table also indicates that sometimes not all columns will show, but doesn't tell under what circumstances.

So I'm looking for guidance: when doesn't it show them all?

I even reordered some of the fields, and merged the HKCU/HKLM path into one field and put that last:

    New-Object PSCustomObject -Property ([Ordered] @{
        "BDS #" = $bdsVersion
        "Name" = $fullName
        "CompilerVersion" = $compilerVersion
        "RTLVersion" = $rtlVersion
        "Define" = $define
        "Characterset" = $characterSet
        "Architectures" = $architecture
        "Frameworks" = $framework
        "DllSuffix" = $dllSuffix
        "ProjectVersion" = $projectVersion
    #    "HKCU" = $hkcuBasePath
    #    "HKLM" = $hklmBasePath
        "HKCU/HKLM registry path" = $basePath
    })

It shows a 165 character wide table (whereas my console Window is 300 characters wide):

Product Summaries:

BDS # Name                    CompilerVersion RTLVersion Define               Characterset Architectures                         Frameworks DllSuffix ProjectVersion
----- ----                    --------------- ---------- ------               ------------ -------------                         ---------- --------- --------------
    1 Borland C# Builder 1    C#              C#         C#                   Unicode      C# .NET 1                             .NET       ????      ????
    2 Borland Delphi 8        none/16.0       none/16.0  VER160/VER160        Ansi/Unicode Win32;.NET 1                          VCL/.NET   80        80
    3 Borland Delphi 2005     17.0/17.0       17.0/17.0  VER170/VER170        Ansi/Unicode Win32;.NET 1                          VCL/.NET   90        ????
    4 Borland Delphi 2006     18.0/18.0       18.0/18.0  VER180/VER180        Ansi/Unicode Win32;.NET 2                          VCL/.NET   100       ????
    5 Borland Delphi 2007     18.5/19.0       18.0/19.0  VER180&VER185/VER190 Ansi/Unicode Win32;.NET 2                          VCL/.NET   100       ????
    6 CodeGear Delphi 2009    20.0            20.0       VER200               Unicode      Win32                                 VCL        120       11.1;12.0
    7 CodeGear Delphi 2010    21.0            21.0       VER210               Unicode      Win32                                 VCL        140       12.0
    8 Embarcadero Delphi XE   22.0            22.0       VER220               Unicode      Win32                                 VCL        150       12.2;12.3
    9 Embarcadero Delphi XE2  23.0            23.0       VER230               Unicode      Win32;Win64                           VCL        160       13.4
   10 Embarcadero Delphi XE3  24.0            24.0       VER240               Unicode      Win32;Win64;OSX32                     VCL;FMX1   170       14.3;14.4
   11 Embarcadero Delphi XE4  25.0            25.0       VER250               Unicode      Win32;Win64;OSX32;iOS-Arm             VCL;FMX2   180       14.6
   12 Embarcadero Delphi XE5  26.0            26.0       VER260               Unicode      Win32;Win64;OSX32;iOS-Arm;Android-Arm VCL;FMX2   190       15.1
   13 Embarcadero Appmethod 1 ????            ????       ????                 Unicode      ????                                  FMX2       ????      ????
   14 Embarcadero Delphi XE6  27.0            27.0       VER270               Unicode      Win32;Win64;OSX32;iOS-Arm;Android-Arm VCL;FMX2   200       15.4
   15 Embarcadero Appmethod 2 ????            ????       ????                 Unicode      ????                                  FMX2       ????      ????

With the path more towards the beginning, the output it 181 characters wide:

BDS # HKCU/HKLM registry path        Name                    CompilerVersion RTLVersion Define               Characterset Architectures                         Frameworks DllSuffix
----- -----------------------        ----                    --------------- ---------- ------               ------------ -------------                         ---------- ---------

With -Wrap, but without -AutoSize the last column doesn't show either.

When leaving the Format-Table away, it does show all fields, so New-Object PSCustomObject -Property does produce all properties:

BDS #                   : 14
HKCU/HKLM registry path : \Software\Embarcadero\BDS\14.0
Name                    : Embarcadero Delphi XE6
CompilerVersion         : 27.0
RTLVersion              : 27.0
Define                  : VER270
Characterset            : Unicode
Architectures           : Win32;Win64;OSX32;iOS-Arm;Android-Arm
Frameworks              : VCL;FMX2
DllSuffix               : 200
ProjectVersion          : 15.4
Community
  • 1
  • 1
Jeroen Wiert Pluimers
  • 23,965
  • 9
  • 74
  • 154

3 Answers3

13

By default, Format-Table will only show 10 columns. To get them all, use "*". See Example and Output below for details.

(FYI: -Wrap is used when the column is being displayed but the data in it is being truncated.)

EXAMPLE:

$aryTemp = @()
$objTemp = New-Object PSObject
$objTemp | Add-Member -type NoteProperty -Name Column1 -Value "Data1"
$objTemp | Add-Member -type NoteProperty -Name Column2 -Value "Data2"
$objTemp | Add-Member -type NoteProperty -Name Column3 -Value "Data3"
$objTemp | Add-Member -type NoteProperty -Name Column4 -Value "Data4"
$objTemp | Add-Member -type NoteProperty -Name Column5 -Value "Data5"
$objTemp | Add-Member -type NoteProperty -Name Column6 -Value "Data6"
$objTemp | Add-Member -type NoteProperty -Name Column7 -Value "Data7"
$objTemp | Add-Member -type NoteProperty -Name Column8 -Value "Data8"
$objTemp | Add-Member -type NoteProperty -Name Column9 -Value "Data9"
$objTemp | Add-Member -type NoteProperty -Name Column10 -Value "Data10"
$objTemp | Add-Member -type NoteProperty -Name Column11 -Value "Data11"
$objTemp | Add-Member -type NoteProperty -Name Column12 -Value "Data12"
$objTemp | Add-Member -type NoteProperty -Name Column13 -Value "Data13"
$objTemp | Add-Member -type NoteProperty -Name Column14 -Value "Data14"
$objTemp | Add-Member -type NoteProperty -Name Column15 -Value "Data15"
$aryTemp += $objTemp

#only shows 10 columns
$aryTemp | Format-Table

#show all
$aryTemp | Format-Table *

OUTPUT:

Column1 Column2 Column3 Column4 Column5 Column6 Column7 Column8 Column9 Column10
------- ------- ------- ------- ------- ------- ------- ------- ------- --------
Data1   Data2   Data3   Data4   Data5   Data6   Data7   Data8   Data9   Data10  



Column1 Column2 Column3 Column4 Column5 Column6 Column7 Column8 Column9 Column10 Column11 Column12 Column13 Column14 Column15
------- ------- ------- ------- ------- ------- ------- ------- ------- -------- -------- -------- -------- -------- --------
Data1   Data2   Data3   Data4   Data5   Data6   Data7   Data8   Data9   Data10   Data11   Data12   Data13   Data14   Data15  
Phry
  • 146
  • 1
  • 4
  • Hmm, now many of my columns get truncated with ellipsis (...) characters, see the output at https://gist.github.com/jpluimers/10c41bb23f1c7361f0ec268ecb378874 Can I get the best of both worlds? – Jeroen Wiert Pluimers Aug 05 '16 at 19:41
  • What are you using to run this code - PowerShell.exe or an IDE? Can you provide the output in a list (so it's non-truncated)? And, what's your code to output look like? – Phry Aug 08 '16 at 14:15
  • I can provide the output in a list; it's this script which I now have truncated to 10 columns. I want to run both from the console as from an IDE. Script: https://bitbucket.org/jeroenp/besharp.net/src/tip/Native/Delphi/Scripts/List-Delphi-Installed-Packages.ps1 where parameter `ProductSummaries` will show the table of summaries for various Delphi versions. The `Get-BDS-ProductSummary` method assembles one entry and I've commented out so I end up at 10 columns per entry. (sorry for late response: I was away without internet for like a week) – Jeroen Wiert Pluimers Aug 14 '16 at 09:13
  • I did; it still wraps the last column: https://gist.github.com/jpluimers/10c41bb23f1c7361f0ec268ecb378874 – Jeroen Wiert Pluimers Aug 15 '16 at 13:25
  • Add a `*` to line 530: `} | Format-Table * -AutoSize -Wrap` Make sure you increase your Screen Buffer Size to something large (apparently PowerShell ISE has no way to increase this). Also, when this works for you you may choice to remove the `-Wrap` so each item is displayed in one line only. – Phry Aug 15 '16 at 13:30
  • Console ScreenBuffer size is already 200 wide; without `Wrap` the fields get ellipsis-truncated: see the updated gist. Basically my question is how to get rid of the artificial ScreenBuffer width when piping this to files. I'm afraid the actual answer is "`Format-Table` is bound to a console so you cannot set the width it uses `AutoSize` or `Wrap`", but if that is so: please add it to your answer and I'll accept it. I've added an example output with the Max console width I could set (480) which does not wrap yet (but will when I add more columns). – Jeroen Wiert Pluimers Aug 15 '16 at 13:42
  • 1
    In that case, you need to add `-Width` to it. Something like this: `.\List-Delphi-Installed-Packages.ps1 ProductSummaries | Out-File -FilePath c:\temp\Delphi.txt -Width 500` Output differences: https://gist.github.com/anonymous/f9f45a86c94643e878eb99c647a59c2c – Phry Aug 17 '16 at 17:48
  • Finally got time to get back to this. Your solution works. Thanks a lot. Where did you find out that `Out-File` and `Format-Table -AutoSize` are related? Based on http://stackoverflow.com/questions/18454653/run-powershell-command-from-command-prompt-no-ps1-script I ended up with this statement: `powershell -command "& .\List-Delphi-Installed-Packages.ps1 ProductSummaries | Out-File -Width 500 tmp1.txt"` Now I need to figure out why `Write-Host` output does not end-up in the text file, but I think I can get around that. – Jeroen Wiert Pluimers Aug 23 '16 at 14:36
  • I found another solution using `Out-String` that also has a `-Width` parameter thanks to https://poshoholic.com/2010/11/11/powershell-quick-tip-creating-wide-tables-with-powershell/ which works even better than `Out-File` as it keeps the flexibility of having the `Format-Table` be processed further down the pipeline. – Jeroen Wiert Pluimers Aug 23 '16 at 19:10
  • 1
    Glad all is working. By the way, check out `-PassThru` so you can log to a file but at the same time display to the console e.g. `Add-Content $Logfile -Value $strTemp -PassThru`. – Phry Aug 24 '16 at 16:17
  • Thanks! That's like `Tee` on steroids (: https://blogs.technet.microsoft.com/heyscriptingguy/2011/11/18/use-the-powershell-passthru-parameter-and-get-back-objects/ – Jeroen Wiert Pluimers Aug 25 '16 at 21:23
2

The easiest and most reliable is to use $FormatEnumerationLimit with -wrap

When things are nested, Format-Table -wrap -Autosize still summarizes things with ...

Test it with a nested object:

$hash = [pscustomobject]@{
   'List' = 0.. 100   
   'files' = (Get-ChildItem ~ ).Name
}

$hash | Format-Table -Wrap -AutoSize
$hash | Format-Table -AutoSize

output:

List          files
----          -----
{0, 1, 2, 3…} {.android, .AndroidStudio, .AndroidStudio2.3, .beautifuldiscord…}


List          files
----          -----
{0, 1, 2, 3…} {.android, .AndroidStudio, .AndroidStudio2.3, .beautifuldiscord…}

Expand the first 10 items

$FormatEnumerationLimit = 10
$hash | Format-Table -AutoSize -Wrap

List                            files
----                            -----
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9…} {.android, .AndroidStudio, .AndroidStudio2.3,
                                .beautifuldiscord, .cache, .cargo, .config, .dbus-keyrings,
                                .dotnet, .fiddler…}

Expand everything $FormatEnumerationLimit = -1

If it's too big it becomes less usable

List
----
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93,
94, 95, 96, 97, 98, 99, 100}

Format-List works better with -1

Get-Module | select Export* | Format-List

Format-Table is good around 15

Piping super wide tables to VS Code

$FormatEnumerationLimit = -1
Get-Module | format-table -AutoSize  | Out-String -Width 9999
ninMonkey
  • 7,211
  • 8
  • 37
  • 66
  • Thanks for the detailed insight. So far I have used the `*` trick mentioned by @Phry in the accepted answer. For future projects, I will try your suggestion and formulate some thoughts on using a global variable to influence a local problem. https://stackoverflow.com/a/38794195/29290 https://community.idera.com/database-tools/powershell/powertips/b/tips/posts/formatenumerationlimit-scoping-issues https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_preference_variables?view=powershell-7 – Jeroen Wiert Pluimers Sep 04 '20 at 13:40
0

So, now you write a lot about the question, for me the way Format-table behave was given by the *.format.ps1xml file given in C:\Windows\System32\WindowsPowerShell\v1.0. But I can't find PSObject, nor PSCustomObject inside (so 9 seems to be the max by default).

Using the -property param of Format-Table, you can show as many properties as you want in the order you want.

Perhaps you can build your one format file using Writing a Windows PowerShell Formatting File, the Microsoft documentation about the subject.

My way of handling your problem is to create a my C# class (type), to insert it using Add-Type, and then to provide a type file and a format file.

JPBlanc
  • 70,406
  • 17
  • 130
  • 175