about_Parameter_Sets

簡単な説明

高度な関数でパラメーター セットを定義して使用する方法について説明します。

詳細な説明

PowerShell では、パラメーター セットを使用して、シナリオごとに異なるアクションを実行できる 1 つの関数を記述できます。 パラメーター セットを使用すると、さまざまなパラメーターをユーザーに公開できます。 そして、ユーザが指定したパラメータに基づいて異なる情報を返す。 一度に使用できるパラメーター セットは 1 つだけです。

パラメーター セットの要件

次の要件は、すべてのパラメーター セットに適用されます。

  • パラメーターにパラメーター セットが指定されていない場合、パラメーターはすべてのパラメーター セットに属します。

  • 各パラメーター セットには、パラメーターの一意の組み合わせが必要です。 可能であれば、少なくとも 1 つの一意のパラメーターを必須パラメーターにする必要があります。

  • 複数の位置指定パラメーターを含むパラメーター セットでは、パラメーターごとに一意の位置を定義する必要があります。 2 つの位置指定パラメーターで同じ位置を指定することはできません。

  • trueの値を持つ ValueFromPipeline キーワードを宣言できるのは、セット内の 1 つのパラメーターだけです。 複数のパラメーターで、値が trueValueFromPipelineByPropertyName キーワードを定義できます。

Note

パラメーター セットは 32 個に制限されています。

既定のパラメーター セット

複数のパラメーター セットが定義されている場合、CmdletBinding 属性の DefaultParameterSetName キーワードは、既定のパラメーター セットを指定します。 PowerShell は、コマンドに指定された情報に基づいて使用するパラメーター セットを決定できない場合に、既定のパラメーター セットを使用します。 CmdletBinding属性の詳細については、about_Functions_CmdletBindingAttributeを参照してください。

パラメーター セットの宣言

パラメーター セットを作成するには、パラメーター セット内のすべてのパラメーターに対して、Parameter 属性のParameterSetName キーワードを指定する必要があります。 複数のパラメーター セットに属するパラメーターの場合は、パラメーター セットごとに Parameter 属性を追加します。

Parameter 属性を使用すると、パラメーター セットごとに異なる方法でパラメーターを定義できます。 たとえば、あるセットでは必須としてパラメーターを定義し、別のセットでは省略可能として定義できます。 ただし、各パラメーター セットには、少なくとも 1 つの一意のパラメーターが含まれている必要があります。

パラメーター セット名が割り当てられないパラメーターは、すべてのパラメーター セットに属します。

次の例の関数は、テキスト ファイル内の行、文字、単語の数をカウントします。 パラメーターを使用して、返す値と測定するファイルを指定できます。 次の 4 つのパラメーター セットが定義されています。

  • Path
  • PathAll
  • LiteralPath
  • LiteralPathAll
function Measure-Lines {
    [CmdletBinding(DefaultParameterSetName = 'Path')]
    param (
        [Parameter(Mandatory, ParameterSetName = 'Path', Position = 0)]
        [Parameter(Mandatory, ParameterSetName = 'PathAll', Position = 0)]
        [string[]]$Path,

        [Parameter(Mandatory, ParameterSetName = 'LiteralPathAll', ValueFromPipeline)]
        [Parameter(Mandatory, ParameterSetName = 'LiteralPath', ValueFromPipeline)]
        [string[]]$LiteralPath,

        [Parameter(ParameterSetName = 'Path')]
        [Parameter(ParameterSetName = 'LiteralPath')]
        [switch]$Lines,

        [Parameter(ParameterSetName = 'Path')]
        [Parameter(ParameterSetName = 'LiteralPath')]
        [switch]$Words,

        [Parameter(ParameterSetName = 'Path')]
        [Parameter(ParameterSetName = 'LiteralPath')]
        [switch]$Characters,

        [Parameter(Mandatory, ParameterSetName = 'PathAll')]
        [Parameter(Mandatory, ParameterSetName = 'LiteralPathAll')]
        [switch]$All,

        [Parameter(ParameterSetName = 'Path')]
        [Parameter(ParameterSetName = 'PathAll')]
        [switch]$Recurse
    )

    begin {
        if ($All) {
            $Lines = $Words = $Characters = $true
        }
        elseif (($Words -eq $false) -and ($Characters -eq $false)) {
            $Lines  = $true
        }
    }
    process {
        if ($Path) {
            $Files = Get-ChildItem -Path $Path -Recurse:$Recurse -File
        }
        else {
            $Files = Get-ChildItem -LiteralPath $LiteralPath -File
        }
        foreach ($file in $Files) {
            $result = [ordered]@{ }
            $result.Add('File', $file.fullname)

            $content = Get-Content -LiteralPath $file.fullname

            if ($Lines) { $result.Add('Lines', $content.Length) }

            if ($Words) {
                $wc = 0
                foreach ($line in $content) { $wc += $line.split(' ').Length }
                $result.Add('Words', $wc)
            }

            if ($Characters) {
                $cc = 0
                foreach ($line in $content) { $cc += $line.Length }
                $result.Add('Characters', $cc)
            }

            New-Object -TypeName psobject -Property $result
        }
    }
}

各パラメーター セットには、一意のパラメーターまたはパラメーターの一意の組み合わせが必要です。 Pathパラメーター セットと PathAll パラメーター セットは非常に似ていますが、All パラメーターは、PathAll パラメーター セットに固有です。 LiteralPathおよびLiteralPathAllパラメーター セットでも同様です。 PathAll パラメーターと LiteralPathAll パラメーター セットの両方に All パラメーターがありますが、Path パラメーターと LiteralPath パラメーターは区別されます。

Get-Command -Syntax使用すると、各パラメーター セットの構文が示されます。 ただし、パラメーター セットの名前は表示されません。 次の例は、各パラメーター セットで使用できるパラメーターを示しています。

(Get-Command Measure-Lines).ParameterSets |
  Select-Object -Property @{n='ParameterSetName';e={$_.name}},
    @{n='Parameters';e={$_.ToString()}}
ParameterSetName Parameters
---------------- ----------
Path             [-Path] <string[]> [-Lines] [-Words] [-Characters] [-Recurse] [<CommonParameters>]
PathAll          [-Path] <string[]> -All [-Recurse] [<CommonParameters>]
LiteralPath      -LiteralPath <string[]> [-Lines] [-Words] [-Characters] [<CommonParameters>]
LiteralPathAll   -LiteralPath <string[]> -All [<CommonParameters>]

動作中のパラメーター セット

この例では、 PathAll パラメーター セットを使用します。

Measure-Lines test* -All
File                       Lines Words Characters
----                       ----- ----- ----------
C:\temp\test\test.help.txt    31   562       2059
C:\temp\test\test.md          30  1527       3224
C:\temp\test\test.ps1          3     3         79
C:\temp\test\test[1].txt      31   562       2059

複数のセットのパラメーターを使用してエラーが発生しました

この例では、さまざまなパラメーター セットの一意のパラメーターが使用されます。

Get-ChildItem -Path $PSHOME -LiteralPath $PSHOME
Get-ChildItem : Parameter set can't be resolved using the specified named parameters.
At line:1 char:1
+ Get-ChildItem -Path $PSHOME -LiteralPath $PSHOME
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [Get-ChildItem], ParameterBindingException
    + FullyQualifiedErrorId : AmbiguousParameterSet,Microsoft.PowerShell.Commands.GetChildItemCommand

Path パラメーターと LiteralPath パラメーターは、Get-ChildItem コマンドレットのさまざまなパラメーター セットに固有です。 パラメーターが同じコマンドレットで一緒に実行されると、エラーがスローされます。 一度に使用できるパラメーター セットは、コマンドレット呼び出しごとに 1 つだけです。

使用されているパラメーター セットを確認する方法

自動変数 $PSCmdlet は、 ParameterSetName プロパティを提供します。 このプロパティには、使用されているパラメーター セットの名前が含まれています。 関数でこのプロパティを使用して、パラメーター セット固有の動作を選択するために使用されているパラメーター セットを決定できます。

function Get-ParameterSetName {

    [CmdletBinding(DefaultParameterSetName = 'Set1')]
    param (
        [Parameter(ParameterSetName = 'Set1', Position = 0)]
        $Var1,

        [Parameter(ParameterSetName = 'Set2', Position = 0)]
        $Var2,

        [Parameter(ParameterSetName = 'Set1', Position = 1)]
        [Parameter(ParameterSetName = 'Set2', Position = 1)]
        $Var3,

        [Parameter(Position = 2)]
        $Var4
    )

    "Using Parameter set named '$($PSCmdlet.ParameterSetName)'"

    switch ($PSCmdlet.ParameterSetName) {
        'Set1' {
            "`$Var1 = $Var1"
            "`$Var3 = $Var3"
            "`$Var4 = $Var4"
            break
        }
        'Set2' {
            "`$Var2 = $Var2"
            "`$Var3 = $Var3"
            "`$Var4 = $Var4"
            break
        }
    }
}

PS> Get-ParameterSetName 1 2 3

Using Parameter set named 'Set1'
$Var1 = 1
$Var3 = 2
$Var4 = 3

PS> Get-ParameterSetName -Var2 1 2 3

Using Parameter set named 'Set2'
$Var2 = 1
$Var3 = 2
$Var4 = 3