Pergunta

Eu gostaria de passar uma matriz associativa de C # para PowerShell. Como exemplo, eu gostaria de executar esta linha powershell de código:


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

Name                                                        Foo
----                                                        ---
Add-Content                                                 Bar
Add-History                                                 Bar
Add-Member                                                  Bar

Eu gostaria de fazer isso através de um gasoduto de distinta Comandos em oposição a um único comando marcado como um script. Aqui está o código:


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());

Mas isso matriz associativa que está sendo passado como um parâmetro para Select-Object não está sendo analisado corretamente. Isto é o que sai do outro lado:


PS C:\test> c:\test\Bin\Debug\test.exe

Name                                     @{N="Foo";E={"Bar"}}
----                                     --------------------
Add-Content
Add-History
Add-Member

O que há de errado com a forma como estou a criação dos parâmetros de comando Select-Object?

Foi útil?

Solução

Criação de um oleoduto através de c # e criando um gasoduto com o script powershell nativa tem uma diferença importante que é realmente muito sutil:. O ligante parâmetro

se eu escrever uma versão de seu código no roteiro pura, eu recebo o mesmo erro:. Literal hashtable é tratado como um valor de string

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"}}'))

Neste caso, o comando recebe um array de duas cordas, o "nome" e a string literal hashtable. Este será quebrado exatamente da mesma forma que o seu C #. Agora, dê uma olhada no caminho certo para fazê-lo (no roteiro) - deixe-me reescrever a linha 3:

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

Então, o que mudou? Eu removi as aspas em torno do hashtable - Eu estou passando uma tabela hash como o 2º elemento da matriz objeto! Assim, para obter o seu C # exemplo para trabalho, você precisa fazer o que o ligante parâmetro faz por nós na linha de comando (que é bastante!). Substituir:

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

com

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

Espero que isso resolve isso para você. O aglutinante parâmetro é provavelmente a parte menos visível, mas mais poderoso da experiência PowerShell.

-Oisin

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top