Why does powershell sometimes pass PSObject (instead of the base object) to .Net code?

I find that in some cases powershell 2.0 passes Object [] arrays containing PSObjects instead of the actual types contained in them when they are passed as a parameter to the .Net code. I think this is a 2.0 bug, but I cannot find any mention of this.

$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)

Fingerprints:

From powershell
  $testdata[0].GetType()         System.Collections.Hashtable
From .Net
  TypeOfNthElement($testdata,0)  System.Management.Automation.PSObject

The last line is very surprising; C # code accepts Object[], containing PSObjectinstead Object[], containing Hashtable. This makes it impossible to use with existing .Net libraries that do not expect PSObject.

Curiously, I can get around the problem if I $h.foo = "bar"use it instead $h["foo"] = "bar".

, - getA getB, .

- $psversiontable, :

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

powershell 2.0 XP, Win7 Windows Server 2008 R2

+3
1

W2K3 PowerShell V2.0, ["hello","world"].

, getdata3 :

function getdata3()
{
  $a
  return " "
}

, , "" script, / .

: $psversiontable PowerShell?

0

All Articles