PowerShellにはまる

これまでの流れで週末からWindows PowerShellについて、いろいろと調べているのだが、これは非常に面白い。例えばCmdLet(コマンドレット)という機能があって、以下のようなC#で書いたクラス(勿論VBでも良いが)から自分だけのコマンドが作れるのだ。

using System;
using System.Collections.Generic;
using System.Text;
using System.Management.Automation;

[Cmdlet("say","hello")]
public class CmdLetTest : Cmdlet {
    private string name;
    
    [Parameter(Mandatory=true, Position=0)]
    public string Name {
        get { return this.name; }
        set { this.name = value; }
    }
    protected override void ProcessRecord() {
        WriteObject("hello " + this.name);
    }
}

これをコンパイルしてできたアセンブリをPowerShellに登録すると、こんな風にコマンドとして起動できる。

PS say-hello 'Kazzz'
hello Kazzz 

ここでもカスタム属性が大活躍している。

  • [Cmdlet("say","hello")]

コマンドレットを定義する。パラメタは動詞+名詞で指定する。つまりこの場合、このコマンドを呼び出す際に使用する文法は"say-hello"ということになる。

  • [Parameter(Mandatory=true, Position=0)]

コマンドのパラメタを定義するMandatory=trueは必須であることを示し、Position=0とはパラメタの並びとして最初に指定するパラメタであることを示している。

コマンドで行う実際の処理はProcessRecord()メソッドをオーバライドしてその中に記述するのだが、ここでは何も値を戻しておらず、代わりにWriteObjectを使用しているのがミソ。先日のエントリで書いていた謎があったが

目下の問題は、Invokeメソッドで戻ったPSObjectクラスのコレクションに、一体どのような結果が返ってくる可能性があるか、現時点では調べていないために全く解らないことだ。現状で判明しているのはスクリプト式の実行が成功した際には、コレクションの序数0の要素に実行結果の戻り値がセットされている、という事実だけである。なさけない話だ。

この謎を解く鍵はここいらにあるのではないかと、現在も調査中。