1

I'm running C# PowerShell code on a remote system and need to get the value of a local variable. PowerShell has a cmdlet named Get-Variable which I'm trying to use. This is my code for trying to fetch the relevant collection of PSVariables (which obviously should contain just one):

psShell.AddScript($"$text = 'someValue'");

psShell.Invoke();

psShell.Commands.Clear();

psShell.AddCommand("Get-Variable")
.AddParameter("Name", "text");

var v = psShell.Invoke<PSVariable>();

Problem is on the last line, I get the following exception:

Cannot convert the "System.Management.Automation.PSVariable" value of type "Deserialized.System.Management.Automation.PSVariable" to type "System.Management.Automation.PSVariable".

Anyone know how to solve this ?

Also, I know of the SessionStateProxy method mentioned on StackOverflow, but as this post of mine shows, it doesn't work for my scenario for some reason.

4
  • I can't reproduce this in PowerShell. I get the variable returned using a generic method. Have you tried setting var v to System.Collections.ObjectModel.Collection<PSVariable>? See Invoke<T>() Commented May 6, 2020 at 0:15
  • I meant changing var to System.Collections.ObjectModel.Collection<PSVariable>. Commented May 6, 2020 at 0:23
  • 1
    While I haven't tried it, it should not help because using var automatically infers the correct data type .. that is it's own point! Commented May 6, 2020 at 2:20
  • I'm aware, I just wanted to to see if something strange was going on and declaring the object explicitly worked. You have an answer anyway. Commented May 6, 2020 at 8:15

1 Answer 1

2

When PowerShell remoting is involved, only a handful of well-known types deserialize with type fidelity, System.Management.Automation.PSVariable not being among them.

Instances of all other types deserialize as method-less emulations of the original objects, as [psobject] instances with properties containing static copies of the original property values.
In PowerShell, these instances report their type name as the original type name prefixed with Deserialized.
See this answer for background information.

The simplest way to handle such objects is via the DLR:

dynamic v = psShell.Invoke();

Then you can access properties as usual (albeit with runtime binding), e.g., v.Name.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.