about_Functions_Argument_Completion

簡短描述

自變數完成是 PowerShell 的一項功能,可提供提示、啟用探索,以及加速自變數值的輸入輸入。

詳細描述

本文說明您可以針對 PowerShell 函式實作自變數完成項的不同方式。 自變數完成項會提供參數的可能值。 當使用者在參數名稱後面按下 Tab 鍵時,會在運行時間計算可用的值。 有數種方式可以定義參數的自變數完成項。

注意

Tab 是 Windows 上的預設索引鍵系結。 PSReadLine 模組或裝載 PowerShell 的應用程式可以變更此密鑰系結。 非 Windows 平臺上的keybinding不同。 如需詳細資訊,請參閱 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('Onion', 'Carrot', 'Lettuce')]
        $Vegetable
    )
}

每個參數都會提供 ArgumentCompletions 屬性的選項清單,以啟用索引標籤自動完成。

這個屬性是在 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) - 此參數設定為值需要 Tab 鍵完成的參數。
  • $wordToComplete (位置 2) - 此參數設定為使用者按下 Tab 之前所提供的值。您的腳本區塊應該使用此值來判斷索引標籤完成值。
  • $commandAst (位置 3) - 此參數設定為目前輸入行的抽象語法樹狀結構 (AST)。 如需詳細資訊,請參閱 AST 類型檔。
  • $fakeBoundParameters(Position 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 = @('Onion', 'Carrot', 'Lettuce')
    }

    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
      )
}

以類別為基礎的自變數完成器

從 PowerShell 7.2 開始,新增了一項新功能,可讓您定義參數化自變數完成項的更多泛型實作。

藉由衍生自 ArgumentCompleterAttribute,即可建立可重複使用的泛型完成項,例如:

[DirectoryCompleter(ContainingFile="pswh.exe", Depth=2)]

[DateCompleter(WeekDay='Monday', From="LastYear")]

[GitCommits(Branch='release')]

衍生屬性必須實作 介面, IArgumentCompleterFactory 並使用屬性值來建立特製化完成項。

using namespace System.Collections
using namespace System.Collections.Generic
using namespace System.Management.Automation
using namespace System.Management.Automation.Language

class NumberCompleter : IArgumentCompleter {

    [int] $From
    [int] $To
    [int] $Step

    NumberCompleter([int] $from, [int] $to, [int] $step) {
        if ($from -gt $to) {
            throw [ArgumentOutOfRangeException]::new("from")
        }
        $this.From = $from
        $this.To = $to
        $this.Step = $step -lt 1 ? 1 : $step
    }

    [IEnumerable[CompletionResult]] CompleteArgument(
        [string] $CommandName,
        [string] $parameterName,
        [string] $wordToComplete,
        [CommandAst] $commandAst,
        [IDictionary] $fakeBoundParameters) {

        $resultList = [List[CompletionResult]]::new()
        $local:to = $this.To
        $local:step = $this.Step
        for ($i = $this.From; $i -lt $to; $i += $step) {
            $resultList.Add([CompletionResult]::new($i.ToString()))
        }

        return $resultList
    }
}

class NumberCompletionsAttribute : ArgumentCompleterAttribute, IArgumentCompleterFactory {
    [int] $From
    [int] $To
    [int] $Step

    NumberCompletionsAttribute([int] $from, [int] $to, [int] $step) {
        $this.From = $from
        $this.To = $to
        $this.Step = $step
    }

    [IArgumentCompleter] Create() { return [NumberCompleter]::new($this.From, $this.To, $this.Step) }
}

接著,來自 PowerShell 的使用量會是:

function Add{
    param(
       [NumberCompletions(0, 100, 5)]
       [int] $X,

       [NumberCompletions(0, 100, 5)]
       [int] $Y
    )
    $X + $Y
}

Register-ArgumentCompleter

Cmdlet Register-ArgumentCompleter 會註冊自定義自變數完成項。 自變數完成器可讓您在執行時間提供您指定之任何命令的動態索引標籤完成。

如需詳細資訊,請參閱 Register-ArgumentCompleter

另請參閱