I'm having difficulty accessing PSObject
s 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.
$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
$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...
$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.
$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.
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!
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
}