Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to access NoteProperties on the InputObject to a remoting session

I'm having difficulty accessing PSObjects with NoteProperties defined, that are being passed through to a remote session via Invoke-Command. The reason I am constructing an object for this purpose is that I need access to two separate pieces of information in the remote session, but PowerShell only provides for a single InputObject.

My code looks something like this:

$sessionInput = new-object -TypeName System.Object
$sessionInput | Add-Member -MemberType NoteProperty -Name NoteProperty1 -Value @("some", "value")
$sessionInput | Add-Member -MemberType NoteProperty -Name NoteProperty2 -Value @("some", "other", "value)
$session = New-PSSession -ComputerName my-computer -Credential (Get-Credential)
Invoke-Command -Session $session -InputObject $sessionInput {
    $input #1
    $input | Get-Member #2
    $input.NoteProperty1 #3
    $input.NoteProperty1 | Get-Member #4
}

I get the following output for each of the numbered lines above.

1. $input

So, first of all I tried my usual technique of dumping the variable to the console, which confirmed that the properties were passed through with the expected value:

NoteProperty1      : {some, value}
NoteProperty2      : {some, other, value}
PSComputerName     : my-computer
RunspaceId         : d1f35c8b-f631-4caa-bae0-f7c0066bbd55
PSShowComputerName : True

2. $input | Get-Member

This generated slightly more information than the previous attempt:

   TypeName: Deserialized.System.Object

WARNING: column "PSComputerName" does not fit into the display and was removed.

Name          MemberType   Definition                                                                                       
----          ----------   ----------                                                                                       
Equals        Method       bool Equals(System.Object obj)                                                                   
GetHashCode   Method       int GetHashCode()                                                                                
GetType       Method       type GetType()                                                                                   
ToString      Method       string ToString(), string ToString(string format, System.IFormatProvider formatProvider)         
NoteProperty1 NoteProperty Deserialized.System.String[] NoteProperty1=some val...
NoteProperty2 NoteProperty Deserialized.System.String[] NoteProperty2=some oth...

Note that the last two lines clearly show the NoteProperty is present on the object received by the remote session. All those mentions of Deserialized are starting to pique my interest...

3. $input.NoteProperty1

Having had some luck with the first two, I started trying to inspect NoteProperty1 itself. However, the value of this property appears to be null; nothing is written to the console using the line above, $input.NoteProperty1 -eq $null returns True.

4. $input.NoteProperty1 | Get-Member

So, last of all, I tried to inspect the NoteProperty1 value directly via Get-Member, which failed miserably with the message "No object has been specified to the get-member cmdlet.", which is consistent with a null object being passed to Get-Member.

Help!

So, I'm completely at a loss now: this Schrödinger property both exists and does not; both has the expected value, and has no value. I think I can write this in a slightly different way that will eliminate the need for the NoteProperties, but I would love to know what's going on here!

like image 574
alastairs Avatar asked Mar 19 '12 17:03

alastairs


1 Answers

Select Object for the win! :)

$SessionInput = New-Object -TypeName System.Object
$SessionInput | Add-Member -MemberType NoteProperty -Name NoteProperty1 -Value @("some", "value")
$SessionInput | Add-Member -MemberType NoteProperty -Name NoteProperty2 -Value @("some", "other", "value")
$Session = New-PSSession -ComputerName 127.0.0.1
Invoke-Command -Session $Session -InputObject $SessionInput {
    [array]$NoteProperty1 = $Input | Select -Expand NoteProperty1
    for ($i = 0; $i -lt $NoteProperty1.Count; $i ++)
    {
        Write-Host -ForeGroundColor "Magenta" $i
        $NoteProperty1[$i]
    }
}

For String variables you still need to expand the string in the select statement like this:

$SessionInput = New-Object -TypeName System.Object
$SessionInput | Add-Member -MemberType NoteProperty -Name NoteProperty1 -Value "SomeValue"
$Session = New-PSSession -ComputerName 127.0.0.1
Invoke-Command -Session $Session -InputObject $SessionInput {
    $NoteProperty1 = $Input | Select -Expand NoteProperty1
    $NoteProperty1
}
like image 89
HungryHippos Avatar answered Sep 28 '22 06:09

HungryHippos