この記事は以前にdevslife.comに掲載したものです。
ある日「PowerShellで独自の結果を返すにはどうすればいいのだろう?」と考えていた。もちろんカスタムコマンドレットを作成すればアセンブリ内でクラスを作ってそれをWriteObjectを使って返してやればいいのだろうけど、スクリプト内でできないものだろうか?と疑問に思った。
そこでPSObjectの登場だ。PSObjectはSystem.Management.Automation名前空間に存在し、いわば.NET FrameworkのSystem.Objectと同じような位置づけである。非常に汎用的なオブジェクトなのだ。PSObjectをインスタンス化してそのメンバーを見てみると・・・
それだけでは使えるものがほとんどない。このオブジェクトにプロパティやメソッドを追加して使えるものにしていこうという魂胆である。
すでにメモリ内に存在するオブジェクトにプロパティやメソッドを追加することは.NETプログラミングではあまり頻繁に行われることではないが、 JavaScriptだとPrototypeとして、.NET Frameworkで言うならばSystem.Reflection.Emitの名前空間に存在するクラスを使って動的にクラス、プロパティ、メソッド、そして最終的にはアセンブリまで作れてしまうのがある。PowerShellで動的にメンバーを追加するにはAdd-Memberというコマンドレットを使用する。ためしに上でインスタンス化したPSObjectにCustomerIDというプロパティを追加してみよう。
すると・・・
一つのインスタンスのPSObjectでは複数の結果を返すことができない。そこでArrayListを使ってみよう。
$Result = New-Object System.Collections.ArrayList
foreach ($i in 1..15)
{
$Cust = New-Object PSObject
$Cust | Add-Member -Name "CustomerID" -MemberType NoteProperty -Value $i
[void] $Result.Add($Cust)
}
$Result | ft -AutoSize
上のスクリプトを.ps1ファイルに保存して実行すると・・・
上の例にはもちろん複数のプロパティを追加すると複数の列の結果が得られる。この結果をパイプを使って次のコマンドレットに渡すことも可能だ。
今回は触れないが-memberTypeにはNotePropertyの他にAliasProperty, CodeProperty, Property, ScriptProperty, Properties, PropertySet, Method, CodeMethod, ScriptMethod, Methods, ParameterizedProperty, MemberSet, Allがある。help Add-Member -detailedで詳細を読んでみてほしい。
コメント