about_Functions_Argument_Completion

简短说明

参数完成是 PowerShell 的一项功能,可提供提示、启用发现并加快参数值的输入。

长说明

本文介绍可为 PowerShell 函数实现参数完成器的不同方法。 参数完成器提供参数的可能值。 当用户在参数名称后按 Tab 键时,会在运行时计算可用值。 有多种方法可以定义参数的参数完成程序。

注意

Tab 是 Windows 上的默认键绑定。 此密钥绑定可由 PSReadLine 模块或托管 PowerShell 的应用程序更改。 键绑定在非 Windows 平台上是不同的。 有关详细信息,请参阅 about_PSReadLine

ValidateSet 属性

ValidateSet 属性为参数或变量指定一组有效值,并启用 Tab 自动补全。 如果参数或变量值与集中的值不匹配,PowerShell 将生成错误。 在以下示例中, Fruit 参数的值只能是 AppleBananaPear

Param(
    [Parameter(Mandatory=$true)]
    [ValidateSet('Apple', 'Banana', 'Pear')]
    [string[]]
    $Fruit
)

在以下示例中,变量 $flavor 的值必须是 ChocolateStrawberryVanilla。 特性 ValidateSet 可用于任何变量,而不仅仅是参数。

[ValidateSet('Chocolate', 'Strawberry', 'Vanilla')]
[string]$flavor = 'Strawberry'

每当在脚本中分配变量时,也会进行验证。

Param(
    [ValidateSet('hello', 'world')]
    [string]$Message
)

$Message = 'bye'

此示例在运行时返回以下错误:

MetadataError: The attribute cannot be added because variable Message with
value bye would no longer be valid.

有关选项卡扩展的详细信息,请参阅 about_Tab_Expansion

使用类的动态 ValidateSet 值

可以使用 在运行时动态生成 ValidateSet 的值。 在以下示例中,变量$Sound的有效值是通过名为 SoundNames 的类生成的,该检查三个文件系统路径中是否有可用的声音文件:

Class SoundNames : System.Management.Automation.IValidateSetValuesGenerator {
    [string[]] GetValidValues() {
        $SoundPaths = '/System/Library/Sounds/',
                      '/Library/Sounds',
                      '~/Library/Sounds'
        $SoundNames = ForEach ($SoundPath in $SoundPaths) {
            If (Test-Path $SoundPath) {
                (Get-ChildItem $SoundPath).BaseName
            }
        }
        return [string[]] $SoundNames
    }
}

然后,类 [SoundNames] 实现为动态 ValidateSet 值,如下所示:

Param(
    [ValidateSet([SoundNames])]
    [string]$Sound
)

注意

IValidateSetValuesGenerator 是在 PowerShell 6.0 中引入的。

ArgumentCompletions 属性

ArgumentCompletions 属性允许您向特定参数添加制表符完成值。 必须为需要 Tab 补全的每个参数定义 ArgumentCompletions 属性。 ArgumentCompletions 属性类似于 ValidateSet。 这两个属性都采用当用户在参数名称后按 Tab 时要显示的值列表。 但是,与 ValidateSet 不同,这些值不会验证,更像是建议。 因此,用户可以提供任何值,而不仅仅是列表中的值。

ArgumentCompletions 属性不应与 ArgumentCompleter 属性混淆,后者需要脚本块来定义选项。 指定的值可用

语法如下所示:

function Test-ArgumentCompletions {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory=$true)]
        [ArgumentCompletions('Fruits', 'Vegetables')]
        $Type,

        [Parameter()]
        [ArgumentCompletions('Apple', 'Banana', 'Orange')]
        $Fruit,

        [Parameter()]
        [ArgumentCompletions('Tomato', 'Corn', 'Squash')]
        $Vegetable
    )
}

每个参数都提供 ArgumentCompletions 属性的选项列表,用于启用 Tab 自动补全。

此属性是在 PowerShell 6.0 中引入的。

ArgumentCompleter 属性

ArgumentCompleter 属性允许向特定参数添加制表符完成值。 必须为需要 Tab 补全的每个参数定义 ArgumentCompleter 属性。

若要添加 ArgumentCompleter 属性,需要定义用于确定值的脚本块。 脚本块必须采用以下指定顺序的以下参数。 参数的名称并不重要,因为值是按位置提供的。

语法如下所示:

function MyArgumentCompleter {
    Param(
        [Parameter(Mandatory)]
        [ArgumentCompleter( {
            param ( $commandName,
                    $parameterName,
                    $wordToComplete,
                    $commandAst,
                    $fakeBoundParameters )
            # Perform calculation of tab completed values here.
        } )]
        $ParamName
    )
}

ArgumentCompleter 脚本块

脚本块参数设置为以下值:

  • $commandName (位置 0) - 此参数设置为脚本块为其提供制表符补全的命令的名称。
  • $parameterName (位置 1) - 此参数设置为其值需要制表符补全的参数。
  • $wordToComplete (位置 2) - 此参数设置为用户在按 Tab 之前提供的值。脚本块应使用此值来确定 Tab 自动补全值。
  • $commandAst (位置 3) - 此参数设置为当前输入行的抽象语法树 (AST) 。 有关详细信息,请参阅 AST 类型文档。
  • $fakeBoundParameters (位置 4) - 在用户按 Tab 之前,此参数设置为包含 $PSBoundParameters cmdlet 的 的哈希表。有关详细信息,请参阅 about_Automatic_Variables

ArgumentCompleter 脚本块必须使用管道(如 ForEach-ObjectWhere-Object或其他合适的方法)展开值。 返回值数组会导致 PowerShell 将整个数组视为 一个 制表符完成值。

以下示例将 Tab 自动补全添加到 Value 参数。 如果仅指定 Value 参数,则显示 Value 的所有可能值或参数。 指定 Type 参数时, Value 参数仅显示该类型的可能值。

此外, -like 运算符可确保如果用户键入以下命令并使用 Tab 补全,则仅返回 Apple

Test-ArgumentCompleter -Type Fruits -Value A

function MyArgumentCompleter{
    param ( $commandName,
            $parameterName,
            $wordToComplete,
            $commandAst,
            $fakeBoundParameters )

    $possibleValues = @{
        Fruits = @('Apple', 'Orange', 'Banana')
        Vegetables = @('Tomato', 'Squash', 'Corn')
    }

    if ($fakeBoundParameters.ContainsKey('Type')) {
        $possibleValues[$fakeBoundParameters.Type] | Where-Object {
            $_ -like "$wordToComplete*"
        }
    } else {
        $possibleValues.Values | ForEach-Object {$_}
    }
}

function Test-ArgumentCompleter {
[CmdletBinding()]
 param (
        [Parameter(Mandatory=$true)]
        [ValidateSet('Fruits', 'Vegetables')]
        $Type,

        [Parameter(Mandatory=$true)]
        [ArgumentCompleter({ MyArgumentCompleter @args })]
        $Value
      )
}

Register-ArgumentCompleter

cmdlet Register-ArgumentCompleter 注册自定义参数完成程序。 参数补全器允许你在运行时为指定的任何命令提供动态 Tab 自动补全。

有关详细信息,请参阅 Register-ArgumentCompleter

另请参阅