powershellobjectrepresentation

PowerShell object representation


There are different ways to represent (display) an object in PowerShell but when it comes to complex objects it is either very verbose or quiet useless:

$Object = @{ 'a' = 1; 'b' = 2 }

Just outputting (Format-Host, or Format-List) returns a multiline output, as:

$Object

Name                           Value
----                           -----
a                              1
b                              2

Converting it to a string "$Object" or $Object.ToString() doesn't reveal anything about its contents:

System.Collections.Hashtable

Converting it to Json $Object |ConvertTo-Json -Compress, gets close to what I would like to see (but a little too expressive cmdlet for what I need):

{"a":1,"b":2}

I wonder whether there is a way access the representation formatting used by PowerShell display cmdlets, as e.g. the value behind the ImmediateBaseObject and BaseObject:

$Object.PSObject

Members             : {System.Object Item(System.Object key) {get;set;}, bool IsReadOnly {get;}, bool IsFixedSize {get;}, bool IsSynchronized {get;}…}
Properties          : {bool IsReadOnly {get;}, bool IsFixedSize {get;}, bool IsSynchronized {get;}, System.Collections.ICollection Keys {get;}…}
Methods             : {Add, Clear, Clone, Contains…}
ImmediateBaseObject : {[a, 1], [b, 2]}                     # <-- This representation
BaseObject          : {[a, 1], [b, 2]}                     #
TypeNames           : {System.Collections.Hashtable, System.Object}

Wishful thinking, I would like to be able to do something like this:

[PowerShellFormat]$Object

And get the same formatting back for any (complex) object as shown behind BaseObject for $Object.PSObject.
As for this case:

{[a, 1], [b, 2]}

Solution

  • JosefZ has provided the crucial pointer:

    # -> '{[a, 1], [b, 2]}'
    '{' + (@( @{ 'a' = 1; 'b' = 2 }.GetEnumerator() ) -join ', ') + '}'
    

    Note:


    Getting an analogous string representation or [pscustomobject] instances is much simpler: Use string interpolation, i.e. embed the object in an expandable (double-quoted) string ("..."):

    $obj = [pscustomobject] @{ 'a' = 1; 'b' = 2 }
    "$obj" # -> '@{a=1; b=2}'
    

    Note:


    Finally, just to demonstrate that PowerShell's formatting system indeed produces the representations above for hashtables and [pscustomobject] instances used as properties:

    @{ 
      hashtable = @{ 'a' = 1; 'b' = 2 }
      pscustomobject = [pscustomobject] @{ 'a' = 1; 'b' = 2 }
    }
    

    Output:

    Name                           Value
    ----                           -----
    pscustomobject                 @{a=1; b=2}
    hashtable                      {[a, 1], [b, 2]}