通过


about_Parameter_Sets

简短说明

介绍如何在高级函数中定义和使用参数集。

详细说明

PowerShell 使用参数集来编写单个函数,该函数可以针对不同的方案执行不同的作。 通过参数集,你可以向用户公开不同的参数。 并且,根据用户指定的参数返回不同的信息。 一次只能使用一个参数集。

参数集要求

以下要求适用于所有参数集。

  • 如果未为参数指定任何参数集,则参数属于所有参数集。

  • 每个参数集必须具有唯一的参数组合。 如果可能,至少一个唯一参数应该是必需参数。

  • 包含多个位置参数的参数集必须为每个参数定义唯一位置。 没有两个位置参数可以指定相同的位置。

注意

有 32 个参数集的限制。

默认参数集

定义多个参数集时,DefaultParameterSetName 属性的 关键字指定默认参数集。 当 PowerShell 无法根据提供给命令的信息确定要使用的参数集时,将使用默认参数集。 有关 CmdletBinding 属性的详细信息,请参阅 about_Functions_CmdletBindingAttribute

声明参数集

若要创建参数集,必须为参数集中的每个参数指定 ParameterSetName 属性的 关键字。 对于属于多个参数集的参数,请为每个参数集添加 参数 属性。

使用 Parameter 属性,可以针对每个参数集以不同的方式定义参数。 例如,可以在一个集中将参数定义为必需参数,并在另一个集中将参数定义为可选参数。 但是,每个参数集必须至少包含一个唯一参数。

没有分配参数集名称的参数属于所有参数集。

保留参数集名称

PowerShell 保留用于特殊处理的参数集名称 __AllParameterSets

__AllParameterSets 如果未使用显式默认名称,则为默认参数集的名称。

ParameterSetNameParameter 属性设置为 __AllParameterSets 等效于不分配 ParameterSetName。 在这两种情况下,参数都属于所有参数集。

注意

CmdletBinding 属性不会阻止将它DefaultParameterSetName设置为 __AllParameterSets 。 如果执行此作,PowerShell 将创建无法由 Parameter 属性正确引用的显式 参数 集。

例子

以下示例函数对文本文件中的行数、字符和单词进行计数。 使用参数,可以指定要返回的值和要度量的文件。 定义了四个参数集:

  • 路径
  • 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
        }
    }
}

每个参数集必须具有唯一参数或参数的唯一组合。 PathPathAll 参数集非常相似,但 All 参数对 PathAll 参数集是唯一的。 LiteralPathLiteralPathAll 参数集也是如此。 尽管 PathAllLiteralPathAll 参数集都具有 All 参数,但 PathLiteralPath 参数区分它们。

使用 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.

PathLiteralPath 参数对于 Get-ChildItem cmdlet 的不同参数集是唯一的。 在同一 cmdlet 中一起运行参数时,将引发错误。 每个 cmdlet 调用一次只能使用一个参数集。

如何知道使用哪个参数集

自动变量 $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