Frage

Ich möchte ein assoziatives Array von C # zu Powershell zu übergeben. Als Beispiel würde Ich mag diese Powershell-Codezeile auszuführen:


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

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

Ich möchte dies über eine Pipeline tun deutliche Befehle zu einem einzigen Befehl als Skript markiert gegenüber. Hier ist der 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());

Aber das assoziative Array, das als Parameter übergibt an Select-Objekt ist nicht korrekt analysiert werden. Dies ist, was aus der anderen Seite kommt:


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

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

Was ist los mit, wie ich die Einstellung der Select-Object Befehlsparameter auf?

War es hilfreich?

Lösung

eine Pipeline durch c # erstellen und eine Pipeline mit nativer Powershell-Skript hat einen großen Unterschied zu schaffen, die tatsächlich sehr subtil ist. Die Parameter Bindemittel

wenn ich eine Version des Codes in reinen Skript schreiben, werde ich den gleichen Fehler. Die Hash-Tabelle wörtliche als String-Wert behandelt wird,

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 diesem Fall erhält der Befehl ein Array von zwei Strings, die „name“ und der Hash-Tabelle Zeichenkette. Dies wird in genau der gleichen Weise wie C # gebrochen werden. Nun, einen Blick auf dem richtigen Weg nehmen, es zu tun (in-Skript) - lassen Sie mich umschreiben Linie 3:

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

Also, was geändert? Ich entfernte die Anführungszeichen um die Hash-Tabelle - Ich bin eine Hash-Tabelle als zweites Element des Objekts Array übergeben! Also, um Ihr C # Beispiel zu arbeiten, müssen Sie tun, was der Parameter Bindemittel für uns tut in der Befehlszeile (das ist ziemlich viel!). Ersetzen Sie:

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

mit

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

Ich hoffe, das es für Sie aufräumt. Der Parameter Bindemittel ist wahrscheinlich der am wenigsten sichtbar, aber stärkster Teil der Powershell-Erfahrung.

-Oisin

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top