C#からPowerShellのスクリプトを呼ぶ方法と戻り値を受け取る方法

こんにちは。
けいぞうです。

今回は「C#からPowerShellのスクリプトを呼ぶ方法と戻り値を受け取る方法」関する記事です。

[目次]

C#からPowerShellのスクリプトを呼ぶ方法と戻り値を受け取る方法

下記、サンプルスクリプトです。

using System;
using System.Management.Automation;
using System.Collections.ObjectModel;
using System.Linq;

namespace TestPSProgram
{
    class Program
    {
        static void Main(string[] args)
        {
            RunspaceInvoke runspaceInvoke = new RunspaceInvoke();

            Collection<PSObject> results = runspaceInvoke.Invoke("C:\\work\\Script\\TestScript.ps1");
            runspaceInvoke.Dispose();
        }
    }
}

最低限の実行なら、こんな感じでたったの3行で実行できます。

必要な参照

12行目のRunspaceInvokeを使用するためには、

System.Managmenet.Automationの参照が必要になります。

PowerShellの実行のために必要なライブラリになります。


System.Management.AutomationWindows SDKをインストールしていれば下記のパスにdllが配置されているので、それを参照しましょう。

C:\Program Files (x86)\Reference Assemblies\Microsoft\WindowsPowerShell\3.0\System.Management.Automation.dll

(各環境により若干のパスの違いはある可能性があります。)


dllが無い場合は、こちらからWindows SDKのインストーラをダウウンロードできますので、これでインストールしてください。

https://developer.microsoft.com/ja-jp/windows/downloads/windows-10-sdk/

戻り値の受け取り方

戻り値の受け取り方についてですが、上記サンプルスクリプトのように、「PSObject」としてPowerShellの戻り値が1つにラップされて返されます。

このPSObjectにどのような戻り値が含まれるかについては、別の記事で触れていますので、そちらをご覧ください。


上記の問題をしたPowerShellの以下のようなスクリプトを呼び出すとします。

#DataTableの作成
$hoge = New-Object System.Data.DataTable

#列の追加
$hoge.Columns.Add("c1") | Out-Null
$hoge.Columns.Add("c2") | Out-Null
$hoge.Columns.Add("c3") | Out-Null

#データ(行)の追加
$hoge.Rows.Add("aaa","bbb","ccc") | Out-Null

$ResultTable = @{
"TargetUser" = $hoge
"result" = 1
}

return $ResultTable

戻り値に含まれるのは、$ResultTableというハッシュテーブル1つだけになります。


C#側でこれを受け取って扱うためには、以下のように記述します。

using System;
using System.Management.Automation;
using System.Collections.ObjectModel;
using System.Linq;
using System.Data;

namespace TestPSProgram
{
    class Program
    {
        static void Main(string[] args)
        {
            RunspaceInvoke runspaceInvoke = new RunspaceInvoke();

            Collection<PSObject> results = runspaceInvoke.Invoke("C:\\work\\Script\\TestScript.ps1");
            runspaceInvoke.Dispose();

            var PSresult = results.OfType<dynamic>();

            foreach (var result in PSresult)
            {
                var dr = result["TargetUser"];
                var resutl = result["result"];
            }
        }
    }
}

こういう感じになります。


PowerShell側できちんと1つのハッシュテーブルだけが返されるように作られていれば、このように取り出したい結果だけを扱うことが可能になります。