How can I convert a hashtable to an array of strings? Suppose $l_table is a hashtable. If I try
$l_array = $l_table | format-table
then $l_arra
David I. McIntosh's own answer works well, but it should be noted that the elements of the resulting array correspond to all lines of the default output, which includes:
Out-String
simply sends what you'd normally see in the console (terminal) to a string, by default as a single string, and with -Stream
as an array of strings.
Here's a variation of David's command that removes both the header and the empty lines:
[string[]] $l_array = ($l_table | Out-String -Stream) -ne '' | select -Skip 2
The rest of this answer shows how to control the specifics of the string representation obtained; it uses PS v3+ syntax and built-in alias %
for ForEach-Object
for brevity.
Note: For clarity, the sample input hashtable is called $ht
(not $l_table
) in the following examples; the PSv4+ .ForEach()
variants perform better.
Get all keys as a string array:
$ht.Keys | % ToString # or (PSv4+): $ht.Keys.ForEach('ToString')
Get all values as a string array:
$ht.Values | % ToString # or (PSv4+): $ht.Values.ForEach('ToString')
Get a custom representation of key-value pairs, in format
; note that .GetEnumerator()
is needed to send the key-value pairs individually through the pipeline; by default, PowerShell passes a hashtable as a whole:
$ht.GetEnumerator() | % { "$($_.Name)=$($_.Value)" }
# or (PSv4+):
$ht.GetEnumerator().ForEach({ "$($_.Name)=$($_.Value)" })
Note that while .ToString()
, which is also applied implicitly during string interpolation (inside "..."
, an expandable string), works well with primitive .NET types (as well as additional numeric types such as [decimal]
and [bigint]
); generally, types will just print their full type name, unless their .ToString()
method is explicitly overridden to return a more meaningful custom representation (which is what the primitive types do and which is the case with only some of the non-primitive types returned by PowerShell cmdlets).
Also note that using an array(-like data structure) inside an expandable string expands to the (stringified) elements concatenation of its elements with the value of the $OFS
preference variable, which defaults to a space char. (e.g., $a='one', 'two'; "$a"
expands to 'one two'
) - see this answer for more information on expandable strings (string interpolation) in PowerShell.
A simple example of choosing a property of a value to represent it in the string:
# Sample hashtable containing a value of a non-built-in type,
# [System.Diagnostics.Process]
$ht = @{ one = 1; two = Get-Process -ID $PID }
# Use the `.Path` property to represent the value.
$ht.GetEnumerator() | % { "$($_.Name)=$($_.Value.Path)" }