about_Functions_Argument_Completion

Kort beskrivning

Slutförande av argument ä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. Argument completers 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 argumenteparameter.

Kommentar

Fliken ä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 tabbar. 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 på valfri variabel, inte bara parametrar.

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

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

Kommentar

Klassen IValidateSetValuesGenerator introducerades i PowerShell 6.0.

Attributet ArgumentCompletions

Med attributet ArgumentCompletions kan du lägga till tabbavslutsvä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('Onion', 'Carrot', 'Lettuce')]
        $Vegetable
    )
}

Var och en av parametrarna tillhandahålls en lista med alternativ till attributet ArgumentCompletions för att aktivera flikslutsättning.

Det här attributet introducerades i PowerShell 6.0.

Attributet ArgumentCompleter

Med attributet ArgumentCompleter kan du lägga till tabbavslutsvä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. Parameterns namn 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 är inställda på följande värden:

  • $commandName (Position 0) – Den här parametern är inställd på namnet på kommandot som skriptblocket tillhandahåller tabbavslut för.
  • $parameterName (Position 1) – Den här parametern är inställd på parametern vars värde kräver att fliken slutförs.
  • $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 flikslutvä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 ast-typdokumentationen.
  • $fakeBoundParameters (Position 4) – Den här parametern är inställd på en hashtable som innehåller cmdleten $PSBoundParameters för 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 kan PowerShell behandla hela matrisen som ett flikslutvärde.

I följande exempel läggs fliken till i parametern Värde . Om endast värdeparametern har angetts 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 om användaren skriver följande kommando och använder Tab completion returneras endast 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
      )
}

Klassbaserade argument-completers

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

Genom att härleda från ArgumentCompleterAttributekan du skapa generiska kompletteringar 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 kompletterare.

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ändning 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 slutförd anpassad argument. Med en argumentföreläsning kan du ange dynamisk flikavslut, vid körning för alla kommandon som du anger.

Mer information finns i Register-ArgumentCompleter.

Se även