C#でPowerShellから受け取った連想配列の中のDataTableを取り出す方法

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

ちょっと表題が長いですが、備忘録として残しておきます。

要するに「PowerShellの戻り値として連想配列(ハッシュテーブル)を受け取ったんだけど、その値にDataTableが含まれていてうまく取り出せないよう!どうすればいいの?

ということがあったので、メモです。

[目次]

PowerShellで戻り値を受け取った部分

ハッシュテーブル自体を取り出している部分は以下のように書いています。

RunspaceInvoke invoker = new RunspaceInvoke();
Collection<PSObject> results = invoker.Invoke("C:\\work\\TestScript.ps1");
invoker.Dispose();

Hashtable ht = (Hashtable)results[results.Count - 1].BaseObject;

PowerShellの戻り値の型は「Collection<PSObject>」です。

その後、resultsの最後尾からハッシュテーブルを取り出していますが、これはPowerShellが戻り値に余計なものをポンポン入れる仕様になっているので、とりあえずreturnしたものだけを取り出したかったらこのやり方が手っ取り早いです。

今回PowerShell側で返しているハッシュテーブルは以下のようにしています。

$hashTable = @{
"Table" = $DataTable
"resultValue" = 1
}

return $hashTable

普通に扱ったらどうなるか

まず値がスカラー値になっている「resuluValue」の方ですが、普通に取り出せます。

// スカラー値の場合
int ResultValue = Int32.Parse(ht["result"].ToString());

同じように配列も取り出してみたいですが・・・

// DataTableの場合
DataTable Dt = (DataTable)ht["Table"];

こう書くとコンパイルは通りますが、キャストエラーになってしまいました。

「型 ‘System.Management.Automation.PSObject’ のオブジェクトを型 ‘System.Data.DataTable’ にキャストできません。」

ht[“Table”]の方は「object{ System.Management.Autometion.PSObject }」という風になっているらしく、コイツをDataTableにキャストできないようです。

キャストする方法

取り出したいDataTableはこのPSObjectの中の「BaseObject」というプロパティに入っているので、そこを参照してキャストすれば取り出せます。

DataTable Dt = (DataTable)((PSObject)ht["Table"]).BaseObject;

たったこれだけの話でしたが、これだけで2時間くらい費やしてしまいました・・・トホホ😢