about_Parameter_Sets

简短说明

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

长说明

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

参数集要求

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

  • 如果某个参数未指定有参数集,则该参数属于所有参数集。

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

  • 包含多个位置参数的参数集必须为每个参数定义唯一位置。 两个位置参数不能指定同一位置。

  • 一个集中只有一个参数可以声明ValueFromPipeline值为 true的关键字 (keyword) 。 多个参数可以定义ValueFromPipelineByPropertyName值为 的true关键字 (keyword) 。

注意

参数集限制为 32 个。

默认参数集

定义多个参数集时,DefaultParameterSetNameCmdletBinding 属性的关键字 (keyword) 将指定默认参数集。 如果 PowerShell 无法根据提供给命令的信息确定要使用的参数集,则使用默认参数集。 有关 CmdletBinding 属性的详细信息,请参阅 about_functions_cmdletbindingattribute

声明参数集

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

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

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

示例

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

  • 路径
  • PathAll
  • LiteralPath
  • LiteralPathAll
function Measure-Lines {
    [CmdletBinding(DefaultParameterSetName = 'Path')]
    param (
        [Parameter(Mandatory = $true,
            ParameterSetName = 'Path',
            HelpMessage = 'Enter one or more filenames',
            Position = 0)]
        [Parameter(Mandatory = $true,
            ParameterSetName = 'PathAll',
            Position = 0)]
        [string[]]$Path,

        [Parameter(Mandatory = $true, ParameterSetName = 'LiteralPathAll')]
        [Parameter(Mandatory = $true,
            ParameterSetName = 'LiteralPath',
            HelpMessage = 'Enter a single filename',
            ValueFromPipeline = $true)]
        [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 = $true, ParameterSetName = 'PathAll')]
        [Parameter(Mandatory = $true, 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
        }

        if ($Path) {
            $Files = Get-ChildItem -Path $Path -Recurse:$Recurse
        }
        else {
            $Files = Get-ChildItem -LiteralPath $LiteralPath
        }
    }
    process {
        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
        }
    }
}

每个参数集必须具有唯一参数或参数的唯一组合。 和 参数集非常相似,但 All 参数对参数集是唯一的PathAllPathAllPath 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 参数对于 cmdlet 的不同参数集是唯一的Get-ChildItem。 当参数在同一 cmdlet 中一起运行时,将引发错误。 每个 cmdlet 调用一次只能使用一个参数集。