about_Parameter_Sets

簡単な説明

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

詳細な説明

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

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

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

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

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

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

  • セット内の 1 つのパラメーターのみが、値trueが のキーワード (keyword)を宣言ValueFromPipelineできます。 複数のパラメーターで、値trueValueFromPipelineByPropertyName 1 のキーワード (keyword)を定義できます。

Note

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

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

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

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

パラメーター セットを作成するには、パラメーター セット内のすべてのパラメーターに対して Parameter 属性のキーワード (keyword)を指定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固有です。 パラメーター セットとLiteralPathLiteralPathAll同じことが当てはまります。 パラメーター セットとLiteralPathAllパラメーター セットのPathAll両方に 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 cannot be resolved using the specified named
parameters. One or more parameters issued cannot be used together or an
insufficient number of parameters were provided.

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