Передача ассоциативного массива из С# в Powershell
-
03-07-2019 - |
Вопрос
Я хотел бы передать ассоциативный массив из С# в Powershell.В качестве примера я хотел бы выполнить эту строку кода PowerShell:
PS C:\> get-command | select name, @{N="Foo";E={"Bar"}} -first 3
Name Foo
---- ---
Add-Content Bar
Add-History Bar
Add-Member Bar
Я хотел бы сделать это через конвейер отчетливый Команды, а не одна команда, помеченная как сценарий.Вот код:
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());
Но этот ассоциативный массив, передаваемый в качестве параметра Select-Object, анализируется неправильно.Вот что получается с другой стороны:
PS C:\test> c:\test\Bin\Debug\test.exe
Name @{N="Foo";E={"Bar"}}
---- --------------------
Add-Content
Add-History
Add-Member
Что не так с тем, как я настраиваю параметры команды Select-Object?
Решение
Создание конвейера с помощью C# и создание конвейера с помощью собственного сценария PowerShell имеют одно существенное различие, которое на самом деле довольно тонкое:связыватель параметров.
если я напишу версию вашего кода в чистом скрипте, я получу ту же ошибку:литерал хеш-таблицы рассматривается как строковое значение.
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"}}'))
В этом случае команда получает массив из двух строк: «имя» и литеральную строку хэш-таблицы.Это будет сломано точно так же, как и ваш C#.Теперь посмотрим, как правильно это сделать (в сценарии) — позвольте мне переписать строку 3:
ps> $ps.Commands[1].Parameters.Add("Property", @("Name", @{N="Foo";E={"Bar"}}))
Так что же изменилось?Я удалил кавычки вокруг хеш-таблицы — я передаю хеш-таблицу как второй элемент массива объектов!Итак, чтобы ваш пример C# заработал, вам нужно сделать то, что для нас делает связыватель параметров в командной строке (а это довольно много!).Заменять:
properties.Add("@{N=\"Foo\";E={\"Bar\"}}");
с
properties.Add(
new Hashtable {
{"N", "Foo"},
{"E", System.Mananagement.Automation.ScriptBlock.Create("\"Foo\"")}
}
);
Надеюсь, это прояснит вам ситуацию.Связывание параметров, вероятно, наименее заметная, но самая мощная часть работы PowerShell.
-Ойсин