質問

C#から連想配列を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スクリプトを使用してパイプラインを作成すると、実際には非常に微妙な違いが1つあります。パラメータバインダーです。

純粋なスクリプトでコードのバージョンを記述した場合、同じエラーが発生します:ハッシュテーブルリテラルは文字列値として扱われます。

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

この場合、コマンドは2つの文字列の配列、" name"を受け取ります。ハッシュテーブルのリテラル文字列。これは、C#とまったく同じように壊れます。次に、それを行う正しい方法(スクリプト内)を見てみましょう。3行目を書き換えてみましょう。

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

では、何が変わったのですか?ハッシュテーブルを囲む引用符を削除しました-ハッシュテーブルをオブジェクト配列の2番目の要素として渡しています!したがって、C#の例を機能させるには、コマンドラインでパラメーターバインダーが行うことを行う必要があります(これは非常に多くのことです!)。置換:

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

with

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

これで解決できることを願っています。パラメータバインダーは、Powershellエクスペリエンスの中で最も見えにくいが最も強力な部分です。

-オイシン

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top