明示的なパラメータを使用した Powershell パラメータ セットの解決が失敗する

明示的なパラメータを使用した Powershell パラメータ セットの解決が失敗する

次のような関数があるとします:

function Foo{
    [CmdLetBinding()]
    param(
        [Parameter(Mandatory=$true,ParameterSetName="A",Position=0)] 
        [Parameter(Mandatory=$true,ParameterSetName="both",Position=0)] 
        [int]
        $A,

        [Parameter(Mandatory=$true,ParameterSetName="B",Position=0)] 
        [Parameter(Mandatory=$true,ParameterSetName="both",Position=1)] 
        [int]
        $B
    )

    Write-Host $PsCmdlet.ParameterSetName

}

この方法では、A または B、あるいはその両方が期待されます。どちらも期待されることはありません。

ただし、これを呼び出すと:

Foo -A 1 -B 2 # outputs "both" as expected
Foo -B 3 # error
Foo -A 4 # error

表示されるエラーは次のとおりです:

Foo : Parameter set cannot be resolved using the specified named parameters.
At c:\pathto:75 char:4
+ Foo <<<<  -B 3
    + CategoryInfo          : InvalidArgument: (:) [Foo], ParameterBindingException
    + FullyQualifiedErrorId : AmbiguousParameterSet,Foo

Foo : Parameter set cannot be resolved using the specified named parameters.
At c:\pathto.ps1:76 char:4
+ Foo <<<<  -A 4
    + CategoryInfo          : InvalidArgument: (:) [Foo], ParameterBindingException
    + FullyQualifiedErrorId : AmbiguousParameterSet,Foo

ご覧のとおり、パラメータの名前を明示的に指定しているため、困りました。

期待どおりに動作する関数をどのように記述すればよいでしょうか?

答え1

おそらく、関数にパラメータチェックを実装する必要があるでしょう。MS によると、パラメータセットには、そのパラメータセットに固有のパラメータが 1 つ必要です。したがって、各パラメータセットには、他のパラメータセットに属していないパラメータが 1 つ必要です。これが、パラメータが 1 つだけの関数を呼び出そうとしたときにエラーが発生する理由です。指定されたパラメータは特定のパラメータセットに固有ではないため、どのパラメータセットを割り当てるかわかりません。私は次のコードで近づきました。

 function Foof{
[CmdLetBinding(DefaultParameterSetName="None")]
param(

    [Parameter(Mandatory=$false,ParameterSetName="A")]
    [Parameter(Position=0)]
    [int]
    $A,

    [Parameter(Mandatory=$false,ParameterSetName="B")]
    [Parameter(Mandatory=$false,ParameterSetName="both")]  
    [Parameter(Position=1)]
    [int]
    $B,

    [Parameter(Mandatory=$false,ParameterSetName="both")]  
    [int]
    $C=$true

)

Write-Host $PsCmdlet.ParameterSetName
write-host "A=$A and B=$B and C=$C"

}

デフォルト値を割り当てると期待どおりの動作が得られると考えましたが$C、関数を呼び出すときにパラメータを明示的に宣言する必要があるため、そうはなりません。

DefaultParameterSetName を「None」に設定していることに気付くでしょう。これにより、どちらのパラメータも送信されなかった場合に、そのケースをすばやくチェックできるようになります。

指定したい変数があるかどうかをチェックし$PsCmdlet.ParameterSetName -eq "None"たり、変数またはのいずれかを指定する必要があるというエラーを出力するなどの操作を実行できます。Read-Hostab

http://technet.microsoft.com/en-us/library/hh847743.aspx

関連情報