about_Functions_Argument_Completion

Kort beskrivning

Argumentkomplettering är en funktion i PowerShell som ger tips, möjliggör identifiering och påskyndar inmatning av argumentvärden.

Lång beskrivning

Den här artikeln beskriver de olika sätt som du kan implementera argument completers för PowerShell-funktioner. Argumenteparametrar anger möjliga värden för en parameter. De tillgängliga värdena beräknas vid körning när användaren trycker på tabbtangenten efter parameternamnet. Det finns flera sätt att definiera en argumentifyllare för en parameter.

Anteckning

Tabb är standardnyckelbindningen i Windows. Den här nyckelbindningen kan ändras av PSReadLine-modulen eller programmet som är värd för PowerShell. Nyckelbindningen skiljer sig från Windows-plattformar. Mer information finns i about_PSReadLine.

Attributet ValidateSet

Attributet ValidateSet anger en uppsättning giltiga värden för en parameter eller variabel och aktiverar tabbifyllning. PowerShell genererar ett fel om en parameter eller ett variabelvärde inte matchar ett värde i uppsättningen. I följande exempel kan värdet för parametern Fruit bara vara Apple, Banana eller Pear.

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

I följande exempel måste värdet för variabeln $flavor vara antingen Chocolate, Strawberry eller Vanilla. Attributet ValidateSet kan användas för alla variabler, inte bara parametrar.

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

Valideringen sker när variabeln tilldelas även i skriptet.

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

$Message = 'bye'

Det här exemplet returnerar följande fel vid körning:

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

Mer information om flikexpansion finns i about_Tab_Expansion.

Dynamiska ValidateSet-värden med hjälp av klasser

Du kan använda en klass för att dynamiskt generera värdena för ValidateSet vid körning. I följande exempel genereras giltiga värden för variabeln $Sound via en klass med namnet SoundNames som kontrollerar tre filsystemsökvägar efter tillgängliga ljudfiler:

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

Klassen [SoundNames] implementeras sedan som ett dynamiskt ValidateSet-värde enligt följande:

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

Anteckning

Klassen IValidateSetValuesGenerator introducerades i PowerShell 6.0.

Attributet ArgumentCompletions

Med attributet ArgumentCompletions kan du lägga till tabbifyllningsvärden till en specifik parameter. Ett ArgumentCompletions-attribut måste definieras för varje parameter som behöver tabbslut. Attributet ArgumentCompletions liknar ValidateSet. Båda attributen tar en lista med värden som ska visas när användaren trycker på Tabb efter parameternamnet. Men till skillnad från ValidateSet verifieras inte värdena och mer som förslag. Därför kan användaren ange valfritt värde, inte bara värdena i listan.

Attributet ArgumentCompletions ska inte förväxlas med attributet ArgumentCompleter, som behöver en scriptblock för att definiera alternativen. de angivna värdena är tillgängliga

Syntaxen ser ut så här:

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

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

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

Var och en av parametrarna tillhandahålls en lista med alternativ för attributet ArgumentCompletions för att aktivera tabbifyllning.

Det här attributet introducerades i PowerShell 6.0.

ArgumentCompleter-attribut

Med attributet ArgumentCompleter kan du lägga till tabbifyllningsvärden till en specifik parameter. Ett ArgumentCompleter-attribut måste definieras för varje parameter som behöver tabbslut.

Om du vill lägga till ett ArgumentCompleter-attribut måste du definiera ett skriptblock som bestämmer värdena. Skriptblocket måste ha följande parametrar i den ordning som anges nedan. Parameternamnen spelar ingen roll eftersom värdena anges positionmässigt.

Syntaxen ser ut så här:

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

ArgumentCompleter-skriptblock

Skriptblockparametrarna anges till följande värden:

  • $commandName (Position 0) – Den här parametern är inställd på namnet på det kommando som skriptblocket tillhandahåller tabbifyllning för.
  • $parameterName (Position 1) – Den här parametern är inställd på den parameter vars värde kräver tabbifyllning.
  • $wordToComplete (Position 2) – Den här parametern är inställd på det värde som användaren har angett innan de trycker på Tabb. Skriptblocket bör använda det här värdet för att fastställa tabbifyllningsvärden.
  • $commandAst (Position 3) – Den här parametern är inställd på AST (Abstract Syntax Tree) för den aktuella indataraden. Mer information finns i dokumentationen om AST-typ .
  • $fakeBoundParameters (Position 4) – Den här parametern är inställd på en hash-tabell som innehåller $PSBoundParameters för cmdleten innan användaren tryckte på Tabb. Mer information finns i about_Automatic_Variables.

Skriptblocket ArgumentCompleter måste avregistrera värdena med pipelinen, till exempel ForEach-Object, Where-Objecteller en annan lämplig metod. Om du returnerar en matris med värden behandlar PowerShell hela matrisen som ett slutförandevärde på en flik.

I följande exempel läggs tabbifyllning till i parametern Value . Om endast värdeparametern anges visas alla möjliga värden eller argument för Värde. När parametern Type anges visar parametern Value endast möjliga värden för den typen.

Dessutom ser operatorn -like till att endast Apple returneras om användaren skriver följande kommando och använder tabbifyllning.

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

Klassbaserade argument som slutförts

Från och med PowerShell 7.2 har en ny funktion lagts till som gör att du kan definiera mer generiska implementeringar av parametriserade argumentimplementerare.

Genom att härleda från ArgumentCompleterAttributekan du skapa generiska kompletterare som kan återanvändas, till exempel:

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

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

[GitCommits(Branch='release')]

De härledda attributen IArgumentCompleterFactory måste implementera gränssnittet och använda egenskapsvärden för att skapa en specialiserad slutförare.

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

Användningen från PowerShell skulle då vara:

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

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

Register-ArgumentCompleter

Cmdleten Register-ArgumentCompleter registrerar en anpassad argument-slutförare. Med en argumentkompletterare kan du ange dynamisk tabbifyllning vid körning för alla kommandon som du anger.

Mer information finns i Register-ArgumentCompleter.

Se även