Eiver Eiver - 3 months ago 9
PowerShell Question

Why single element hashtable behaves differently in powershell?

Code sample:

function ToArray([hashtable] $hashTable){
$ret = @()
foreach($key in $hashTable.Keys){
$ret += ("`"" + $key + ":" + $hashTable[$key] + "`"")
}
$ret
}


$h1 = @{
key1 = "value1" # Only one key in this one
}

$h2 = @{
key2 = "value2"
key3 = "value3"
}

$h3 = @{
key4 = "value4"
key5 = "value5"
}


$test1 = ToArray $h1
$test1 += ToArray $h3

$test2 = ToArray $h2
$test2 += ToArray $h3

Write-Host
Write-Host "TEST 1:" $test1
Write-Host "TEST 2:" $test2


Output:

TEST 1: "key1:value1""key5:value5" "key4:value4"
TEST 2: "key3:value3" "key2:value2" "key5:value5" "key4:value4"


Question:
Why there is a missing space in TEST 1?

Answer

Run the following at the end of your script:

PS Y:\> $test1.GetType()
PS Y:\> $test2.GetType()

IsPublic IsSerial Name                                     BaseType            
-------- -------- ----                                     --------            
True     True     String                                   System.Object       
True     True     Object[]   

One is of type String and the other an Object Array, when you have a single element hashtable, PowerShell sees it as a single string when assigning it to a variable.

PS Y:\> $test1 = ToArray $h1
PS Y:\> $test1.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     String                                   System.Object

So PowerShell will then concatenate all the elements in $h3 into one large string when using +=, as you are adding a Array to a String.

Whereas $test2 to you are adding an Array to and Array meaning you will see the output as one larger array output.

To get round this explicitly define $test1's type to and Array:

[array]$test1 = $h1