簡単な説明
高度な関数でパラメーター セットを定義して使用する方法について説明します。
長い説明
PowerShell では、パラメーター セットを使用して、シナリオごとに異なるアクションを実行できる 1 つの関数を記述できます。 パラメーター セットを使用すると、さまざまなパラメーターをユーザーに公開できます。 そして、ユーザが指定したパラメータに基づいて異なる情報を返す。 一度に使用できるパラメーター セットは 1 つだけです。
パラメーター セットの要件
次の要件は、すべてのパラメーター セットに適用されます。
パラメーターにパラメーター セットが指定されていない場合、パラメーターはすべてのパラメーター セットに属します。
各パラメーター セットには、パラメーターの一意の組み合わせが必要です。 可能であれば、少なくとも 1 つの一意のパラメーターを必須パラメーターにする必要があります。
複数の位置指定パラメーターを含むパラメーター セットでは、パラメーターごとに一意の位置を定義する必要があります。 2 つの位置指定パラメーターで同じ位置を指定することはできません。
Note
パラメーター セットは 32 個に制限されています。
既定のパラメーター セット
複数のパラメーター セットが定義されている場合、DefaultParameterSetName 属性の キーワードは、既定のパラメーター セットを指定します。
PowerShell は、コマンドに指定された情報に基づいて使用するパラメーター セットを決定できない場合に、既定のパラメーター セットを使用します。
CmdletBinding属性の詳細については、about_Functions_CmdletBindingAttributeを参照してください。
パラメーター セットの宣言
パラメーター セットを作成するには、パラメーター セット内のすべてのパラメーターに対して、ParameterSetName 属性の キーワードを指定する必要があります。 複数のパラメーター セットに属するパラメーターの場合は、パラメーター セットごとに Parameter 属性を追加します。
Parameter 属性を使用すると、パラメーター セットごとに異なる方法でパラメーターを定義できます。 たとえば、あるセットでは必須としてパラメーターを定義し、別のセットでは省略可能として定義できます。 ただし、各パラメーター セットには、少なくとも 1 つの一意のパラメーターが含まれている必要があります。
パラメーター セット名が割り当てられないパラメーターは、すべてのパラメーター セットに属します。
予約済みパラメーター セット名
PowerShell は、特別な処理のためにパラメーター セット名 __AllParameterSets を予約します。
__AllParameterSets は、明示的な既定の名前が使用されていない場合に設定される既定のパラメーターの名前です。
ParameterSetName 属性のを __AllParameterSets に設定することは、ParameterSetNameを割り当てないのと同じです。 どちらの場合も、パラメーターはすべてのパラメーター セットに属します。
Note
CmdletBinding 属性では、DefaultParameterSetNameを __AllParameterSets に設定することはできません。 これを行うと、PowerShell は、Parameter 属性で正しく参照できない明示的な パラメーター セットを作成します。
例示
次の例の関数は、テキスト ファイル内の行、文字、単語の数をカウントします。 パラメーターを使用して、返される値と測定するファイルを指定できます。 次の 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 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
PowerShell