I am finding that in some circumstances, powershell 2.0 is passing Object[] arrays containing PSObjects - instead of the real contained types - when passed as a param to .Net code. I think this is a powershell 2.0 bug, but I can't find any mention of it.
$Source = @"
public static class DotNetTypeInfo
{
public static string TypeOfNthElement(object[] oa, int n)
{
return oa[n].GetType().ToString();
}
}
"@
Add-Type -TypeDefinition $Source -Language CSharp
$h = @{}
$h.foo = "bar"
#$h["foo"] = "bar" # uncomment this to fix! (Why?)
$testdata = @($h) # To .net, passed Object[] containing PSObject, not Hashtable!
# other examples that behave similarly badly - uncomment to try
$a = (1,2) # should result in an arry of System.Int32
function getA() { $a } # uncaptured value returned
function getB() { return $a } # explicit return
# $testdata = $a # this works fine
# $testdata = getA # also fine
# $testdata = getB # To .net, passed Object[] containing PSObject, not Int32!
Write-Host "From powershell"
' $testdata[0].GetType() ' + $testdata[0].GetType().ToString()
Write-Host "From .Net"
' TypeOfNthElement($testdata,0) ' + [DotNetTypeInfo]::TypeOfNthElement($testdata,0)
This prints:
From powershell
$testdata[0].GetType() System.Collections.Hashtable
From .Net
TypeOfNthElement($testdata,0) System.Management.Automation.PSObject
The last line is very surprising; the C# code is receiving an Object[]
containing PSObject
instead of an Object[]
containing Hashtable
. This makes it impossible to use with existing .Net libraries that aren't expecting a PSObject.
Curiously, I can work around the problem if I use $h["foo"] = "bar"
instead of $h.foo = "bar"
.
I also see similar effects depending on how you return values from a function - uncomment the getA
and getB
examples to try.
By request - selected highlights from $psversiontable
, edited for brevity:
Key : CLRVersion, Value : 2.0.50727.5472
Key : BuildVersion, Value : 6.1.7601.17514
Key : PSVersion, Value : 2.0
Key : PSCompatibleVersions, Value : {1.0, 2.0}
Key : SerializationVersion, Value : 1.1.0.1
I can replicate this problem using powershell 2.0 on XP, Win7 and Windows Server 2008 R2