Why does ScriptBlock convert Hashtable to Collection and how to avoid it? Why does ScriptBlock convert Hashtable to Collection and how to avoid it? powershell powershell

Why does ScriptBlock convert Hashtable to Collection and how to avoid it?


Have a look at InvokeReturnAsIs method:

[Hashtable] $t = @{} function foo($x) { $x }$t2 = foo $t$t3 = {param([Hashtable] $foo) [Hashtable]$foo}.InvokeReturnAsIs($t)Write-Host $t.GetType()Write-Host $t2.GetType()Write-Host $t3.GetType()

Which outputs:

System.Collections.HashtableSystem.Collections.HashtableSystem.Collections.Hashtable

It seems to give the result you are looking for, but the documentation does not give much informations


I believe the Hashtable gets converted to Collection due to a call of the ScriptBlock.Invoke method. Its return type is System.Collections.ObjectModel.Collection<System.Management.Automation.PSObject>.

Looks like this can be circumvented by invoking the script block via Invoke-Command:

[Hashtable] $t = @{} $t5 = Invoke-Command -ScriptBlock {param([Hashtable] $x) [Hashtable]$x} -ArgumentList $t$t6 = Invoke-Command -ScriptBlock $function:foo -ArgumentList $tWrite-Host "Invoke-Command on script block      " $t5.GetType()Write-Host "Invoke-Command on function variable " $t6.GetType()

This outputs:

Invoke-Command on script block        System.Collections.HashtableInvoke-Command on function variable   System.Collections.Hashtable