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_array is an array, but an array of "FormatEntryData" objects. If I do
[string[]]$l_array = $l_table | format-table
then $l_array is an array of strings, but the strings are all "Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData". If I try
$l_array = $l_table | out-string
then $l_array is a single string. I've tried lots of other things, but nothing works, short of manually looping through, which I really don't want to do.
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 <key>=<value>
; 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)" }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With