Pass associative array from C # to Powershell

I want to pass an associative array from C # to Powershell. As an example, I would like to execute this line of powershell code:

PS C:\> get-command | select name, @{N="Foo";E={"Bar"}} -first 3 Name Foo ---- --- Add-Content Bar Add-History Bar Add-Member Bar 

I would like to do this through Pipeline of individual commands, and not a single command marked as a script. Here is the code:

 Runspace runspace = RunspaceFactory.CreateRunspace(); runspace.Open(); Pipeline pipeline = runspace.CreatePipeline(); pipeline.Commands.Add("get-command"); Command c = new Command("select-object"); List properties = new List(); properties.Add("name"); properties.Add("@{N=\"Foo\";E={\"Bar\"}}"); c.Parameters.Add("Property", properties.ToArray()); c.Parameters.Add("First", 3); pipeline.Commands.Add(c); pipeline.Commands.Add("Out-String"); Collection retval = pipeline.Invoke(); runspace.Close(); StringBuilder stringBuilder = new StringBuilder(); foreach (PSObject obj in retval) Console.WriteLine(obj.ToString()); 

But this associative array passed as a Select-Object parameter is not processed correctly. This is what goes the other way:

 PS C:\test> c:\test\Bin\Debug\test.exe Name @{N="Foo";E={"Bar"}} ---- -------------------- Add-Content Add-History Add-Member 

What is wrong as I adjust the parameters of the Select-Object command?

+7
c # associative-array powershell
source share
1 answer

Creating a pipeline through C # and creating a pipeline with a native powershell script have one significant difference, which is actually pretty subtle: parameter binding.

if I write the version of your code in a pure script, I will get the same error: the hash table literal is treated as a string value.

 ps> $ps = $ps.Commands.Add("get-process") ps> $ps = $ps.Commands.Add("select-object") ps> $ps.Commands[1].Parameters.Add("Property", @("Name", '@{N="Foo";E={"Bar"}}')) 

In this case, the command receives an array of two lines, a string "name" and a hash table row. This will be broken just like your C #. Now take a look at the correct way to do this (in a script) - let me rewrite line 3:

 ps> $ps.Commands[1].Parameters.Add("Property", @("Name", @{N="Foo";E={"Bar"}})) 

So what has changed? I removed the quotation marks around the hash table - I pass the hash table as the 2nd element of the array of objects! So, for your C # example to work, you need to do what the parameter binds for us on the command line (that's pretty much!). Replace:

 properties.Add("@{N=\"Foo\";E={\"Bar\"}}"); 

from

 properties.Add( new Hashtable { {"N", "Foo"}, {"E", System.Mananagement.Automation.ScriptBlock.Create("\"Foo\"")} } ); 

I hope this cleanses you. The binding parameter value is probably the least visible, but the most powerful part of the powershell experience.

-Oisin

+13
source share

All Articles