8. Instructies

8.1 Instructieblokken en lijsten

Syntaxis:

Tip

De ~opt~ notatie in de syntaxisdefinities geeft aan dat de lexicale entiteit optioneel is in de syntaxis.

statement-block:
    new-lines~opt~ { statement-list~opt~ new-lines~opt~ }

statement-list:
    statement
    statement-list statement

statement:
    if-statement
    label~opt~ labeled-statement
    function-statement
    flow-control-statement statement-terminator
    trap-statement
    try-statement
    data-statement
    inlinescript-statement
    parallel-statement
    sequence-statement
    pipeline statement-terminator

statement-terminator:
    ;
    new-line-character

Beschrijving:

Een instructie geeft een soort actie op die moet worden uitgevoerd. Tenzij anders wordt aangegeven in deze component, worden instructies uitgevoerd in lexicale volgorde.

Met een instructieblok kan een set instructies worden gegroepeerd in één syntactische eenheid.

8.1.1 Gelabelde instructies

Syntaxis:

labeled-statement:
    switch-statement
    foreach-statement
    for-statement
    while-statement
    do-statement

Beschrijving:

Een iteratie-instructie (§8.4) of een schakelinstructie (§8.6) kan eventueel worden voorafgegaan door één instructielabel, label. Een instructielabel wordt gebruikt als het optionele doel van een onderbrekingsinstructie (§8.5.1) of doorgaan (§8.5.2). Een label verandert echter niet de controlestroom.

Witruimte is niet toegestaan tussen de dubbele punt (:) en het token dat erop volgt.

Voorbeelden:

:go_here while ($j -le 100) {
    # ...
}

:labelA
for ($i = 1; $i -le 5; ++$i) {
    :labelB
    for ($j = 1; $j -le 3; ++$j) {
        :labelC
        for ($k = 1; $k -le 2; ++$k) {
            # ...
        }
    }
}

8.1.2 Instructiewaarden

De waarde van een instructie is de cumulatieve set waarden die naar de pijplijn worden geschreven. Als de instructie één scalaire waarde schrijft, is dat de waarde van de instructie. Als de instructie meerdere waarden schrijft, is de waarde van de instructie de set waarden die zijn opgeslagen in elementen van een niet-getrainde 1-dimensionale matrix, in de volgorde waarin ze zijn geschreven. Kijk eens naar het volgende voorbeeld:

$v = for ($i = 10; $i -le 5; ++$i) { }

Er zijn geen iteraties van de lus en er wordt niets naar de pijplijn geschreven. De waarde van de instructie is $null.

$v = for ($i = 1; $i -le 5; ++$i) { }

Hoewel de lus vijf keer wordt herhaald, wordt er niets naar de pijplijn geschreven. De waarde van de instructie is $null.

$v = for ($i = 1; $i -le 5; ++$i) { $i }

De lus herhaalt vijf keer telkens wanneer de waarde $inaar de pijplijn int wordt geschreven. De waarde van de instructie is object[] lengte 5.

$v = for ($i = 1; $i -le 5; ) { ++$i }

Hoewel de lus vijf keer wordt herhaald, wordt er niets naar de pijplijn geschreven. De waarde van de instructie is $null.

$v = for ($i = 1; $i -le 5; ) { (++$i) }

De lus wordt vijf keer herhaald met elke waarde die naar de pijplijn wordt geschreven. De waarde van de instructie is object[] lengte 5.

$i = 1; $v = while ($i++ -lt 2) { $i }

De lus wordt één keer herhaald. De waarde van de instructie is de int waarde 2.

Hier volgen enkele andere voorbeelden:

# if $count is not currently defined then define it with int value 10
$count = if ($count -eq $null) { 10 } else { $count }

$i = 1
$v = while ($i -le 5) {
    $i                   # $i is written to the pipeline
    if ($i -band 1) {

        "odd"            # conditionally written to the pipeline

    }

    ++$i                 # not written to the pipeline

}
# $v is object[], Length 8, value 1,"odd",2,3,"odd",4,5,"odd"

8.2 Pijplijninstructies

Syntaxis:

pipeline:
    assignment-expression
    expression redirections~opt~ pipeline-tail~opt~
    command verbatim-command-argument~opt~ pipeline-tail~opt~

assignment-expression:
    expression assignment-operator statement

pipeline-tail:
    | new-lines~opt~ command
    | new-lines~opt~ command pipeline-tail

command:
    command-name command-elements~opt~
    command-invocation-operator command-module~opt~ command-name-expr command-elements~opt~

command-invocation-operator: one of
    &   .

command-module:
    primary-expression

command-name:
    generic-token
    generic-token-with-subexpr

generic-token-with-subexpr:
    No whitespace is allowed between ) and command-name.
    generic-token-with-subexpr-start statement-list~opt~ )

command-namecommand-name-expr:
    command-name

primary-expressioncommand-elements:
    command-element
    command-elements command-element

command-element:
    command-parameter
    command-argument
    redirection

command-argument:
    command-name-expr

verbatim-command-argument:
    --% verbatim-command-argument-chars

Beschrijving:

omleidingen worden besproken in §7.12; toewijzingsexpressie wordt besproken in §7.11; en de command-invocation-operator dot (.) wordt besproken in §3.5.5. Zie §8.14 voor een bespreking van argument-naar-parametertoewijzing in opdracht-aanroepen.

De eerste opdracht in een pijplijn is een expressie of een opdrachtaanroep. Normaal gesproken begint een aanroep van een opdracht met een opdrachtnaam, wat meestal een lege id is. command-elements vertegenwoordigt de lijst met argumenten voor de opdracht. Een nieuwe regel of n niet-gescapede puntkomma beëindigt een pijplijn.

Een aanroep van een opdracht bestaat uit de naam van de opdracht, gevolgd door nul of meer argumenten. De regels voor argumenten zijn als volgt:

  • Een argument dat geen expressie is, maar willekeurige tekst bevat zonder ongezichtige witruimte, wordt behandeld alsof deze dubbel aanhalingeert. Lettercase blijft behouden.

  • Variabele vervanging en subexpressieuitbreiding (§2.3.5.2) vindt plaats binnen expandable-string-literal s en expandable-here-string-literal s.

  • Met tekst tussen aanhalingstekens kunnen voorloop-, volg- en ingesloten witruimte worden opgenomen in de waarde van het argument. [Opmerking: De aanwezigheid van witruimte in een aanhalingsargument verandert niet in één argument in meerdere argumenten. eindnotitie]

  • Als u haakjes rond een argument plaatst, wordt die expressie geëvalueerd met het resultaat dat wordt doorgegeven in plaats van de tekst van de oorspronkelijke expressie.

  • Als u een argument wilt doorgeven dat lijkt op een schakelparameter (§2.3.4), maar als zodanig niet is bedoeld, plaatst u dat argument tussen aanhalingstekens.

  • Wanneer u een argument opgeeft dat overeenkomt met een parameter met de [switch] typebeperking (§8.10.5), zorgt de aanwezigheid van de argumentnaam zelf ervoor dat die parameter wordt ingesteld op $true. De waarde van de parameter kan echter expliciet worden ingesteld door een achtervoegsel toe te voegen aan het argument. Bijvoorbeeld, op basis van een type beperkte parameter p, een argument van -p:$true sets p op True, terwijl -p:$false p wordt ingesteld op Onwaar.

  • Een argument van -- geeft aan dat alle argumenten na deze moeten worden doorgegeven in hun werkelijke vorm alsof dubbele aanhalingstekens eromheen zijn geplaatst.

  • Een argument van --% geeft aan dat alle argumenten die erop volgen, moeten worden doorgegeven met minimale parsering en verwerking. Dit argument wordt de exacte parameter genoemd. Argumenten na de exacte parameter zijn geen PowerShell-expressies, zelfs niet als ze syntactisch geldige PowerShell-expressies zijn.

Als het opdrachttype Application is, wordt de parameter --% niet doorgegeven aan de opdracht. De argumenten nadat --% omgevingsvariabelen (tekenreeksen tussen %) zijn uitgevouwen. Bijvoorbeeld:

echoargs.exe --% "%path%" # %path% is replaced with the value $env:path

De volgorde van de evaluatie van argumenten is niet opgegeven.

Zie §8.14 voor informatie over parameterbinding. Zie §3.8 voor meer informatie over naamzoekacties.

Zodra het verwerken van argumenten is voltooid, wordt de opdracht aangeroepen. Als de aangeroepen opdracht normaal wordt beëindigd (§8.5.4), keert het besturingselement terug naar het punt in het script of de functie direct na de aanroep van de opdracht. Zie voor een beschrijving van het gedrag bij abnormale beëindiging break (§8.5.1), continue (§8.5.2), throw (§8.5.3), exit (§8.5.5), try (§8.7) en trap (§8.8).

Normaal gesproken wordt een opdracht aangeroepen met behulp van de naam, gevolgd door argumenten. De operator voor het aanroepen van opdrachten, &, kan echter worden gebruikt. Als de opdrachtnaam een niet-gescapede witruimte bevat, moet deze worden aangeroepen met deze operator. Omdat een scriptblok geen naam heeft, moet het ook worden aangeroepen met deze operator. De volgende aanroepen van een opdrachtoproep Get-Factorial zijn bijvoorbeeld gelijkwaardig:

Get-Factorial 5
& Get-Factorial 5
& "Get-Factorial" 5

Directe en indirecte recursieve functie-aanroepen zijn toegestaan. Bijvoorbeeld:

function Get-Power([int]$x, [int]$y) {
    if ($y -gt 0) { return $x * (Get-Power $x (--$y)) }
    else { return 1 }
}

Voorbeelden:

New-Object 'int[,]' 3,2
New-Object -ArgumentList 3,2 -TypeName 'int[,]'

dir e:\PowerShell\Scripts\*statement*.ps1 | Foreach-Object {$_.Length}

dir e:\PowerShell\Scripts\*.ps1 | Select-String -List "catch" | Format-Table path,linenumber -AutoSize

8.3 De if-instructie

Syntaxis:

if-statement:
    if new-lines~opt~ ( new-lines~opt~ pipeline new-lines~opt~ ) statement-block
        elseif-clauses~opt~ else-clause~opt~

elseif-clauses:
    elseif-clause
    elseif-clauses elseif-clause

elseif-clause:
    new-lines~opt~ elseif new-lines~opt~ ( new-lines~opt~ pipeline new-lines~opt~ ) statement-block

else-clause:
    new-lines~opt~ else statement-block

Beschrijving:

De expressies voor pijplijnbeheer moeten een type bool hebben of impliciet kunnen worden geconverteerd naar dat type. De else-component is optioneel. Er kunnen nul of meer elseif-componenten zijn.

Als de pijplijn op het hoogste niveau Waar test, wordt het instructieblok uitgevoerd en wordt de uitvoering van de instructie beëindigd. Als er anders een elseif-component aanwezig is, als de pijplijn waar test, wordt het instructieblok uitgevoerd en wordt de uitvoering van de instructie beëindigd. Als er anders een else-component aanwezig is, wordt het instructieblok uitgevoerd.

Voorbeelden:

$grade = 92
if ($grade -ge 90) { "Grade A" }
elseif ($grade -ge 80) { "Grade B" }
elseif ($grade -ge 70) { "Grade C" }
elseif ($grade -ge 60) { "Grade D" }
else { "Grade F" }

8.4 Iteratie-instructies

8.4.1 De instructie while

Syntaxis:

while-statement:
    while new-lines~opt~ ( new-lines~opt~ while-condition new-lines~opt~ ) statement-block

while-condition:
    new-lines~opt~ pipeline

Beschrijving:

De controle-expressie terwijl voorwaarde moet type bool hebben of impliciet converteerbaar zijn naar dat type. De lustekst, die bestaat uit instructieblok, wordt herhaaldelijk uitgevoerd totdat de controle-expressie False test. De controle-expressie wordt geëvalueerd vóór elke uitvoering van de lustekst.

Voorbeelden:

$i = 1
while ($i -le 5) {                     # loop 5 times
    "{0,1}`t{1,2}" -f $i, ($i*$i)
    ++$i
}

8.4.2 De do-instructie

Syntaxis:

do-statement:
    do statement-block new-lines~opt~ while new-lines~opt~ ( while-condition new-lines~opt~ )
    do statement-block new-lines~opt~ until new-lines~opt~ ( while-condition new-lines~opt~ )

while-condition:
    new-lines~opt~ pipeline

Beschrijving:

De controle-expressie terwijl voorwaarde moet type bool hebben of impliciet converteerbaar zijn naar dat type. In de vorm van de tijdje wordt de lustekst, die bestaat uit instructieblok, herhaaldelijk uitgevoerd terwijl de controle-expressie Waar test. In het formulier totdat de hoofdtekst van de lus herhaaldelijk wordt uitgevoerd totdat de controle-expressie Waar test. De controle-expressie wordt geëvalueerd na elke uitvoering van de lustekst.

Voorbeelden:

$i = 1
do {
    "{0,1}`t{1,2}" -f $i, ($i * $i)
}
while (++$i -le 5)                 # loop 5 times

$i = 1
do {
    "{0,1}`t{1,2}" -f $i, ($i * $i)
}
until (++$i -gt 5)                 # loop 5 times

8.4.3 De for-instructie

Syntaxis:

for-statement:
    for new-lines~opt~ (
        new-lines~opt~ for-initializer~opt~ statement-terminator
        new-lines~opt~ for-condition~opt~ statement-terminator
        new-lines~opt~ for-iterator~opt~
        new-lines~opt~ ) statement-block

    for new-lines~opt~ (
        new-lines~opt~ for-initializer~opt~ statement-terminator
        new-lines~opt~ for-condition~opt~
        new-lines~opt~ ) statement-block

    for new-lines~opt~ (
        new-lines~opt~ for-initializer~opt~
        new-lines~opt~ ) statement-block

for-initializer:
    pipeline

for-condition:
    pipeline

for-iterator:
    pipeline

Beschrijving:

De controle-expressie voor voorwaarde moet type bool hebben of impliciet converteerbaar zijn naar dat type. De lustekst, die bestaat uit instructieblok, wordt herhaaldelijk uitgevoerd terwijl de controle-expressie Waar test. De controle-expressie wordt geëvalueerd vóór elke uitvoering van de lustekst.

Expressie voor initialisatie wordt geëvalueerd vóór de eerste evaluatie van de controle-expressie. Expressie voor initialisatie wordt alleen geëvalueerd voor de bijwerkingen; elke waarde die wordt geproduceerd, wordt verwijderd en wordt niet naar de pijplijn geschreven.

Expressie voor iterator wordt geëvalueerd na elke uitvoering van de lustekst. Expressie voor iterator wordt alleen geëvalueerd voor de bijwerkingen; elke waarde die wordt geproduceerd, wordt verwijderd en wordt niet naar de pijplijn geschreven.

Als de expressie voor voorwaarde wordt weggelaten, test de controle-expressie Waar.

Voorbeelden:

for ($i = 5; $i -ge 1; --$i) { # loop 5 times
    "{0,1}`t{1,2}" -f $i, ($i * $i)
}

$i = 5
for (; $i -ge 1; ) { # equivalent behavior
    "{0,1}`t{1,2}" -f $i, ($i * $i)
    --$i
}

8.4.4 De foreach-instructie

Syntaxis:

foreach-statement:
    foreach new-lines~opt~ foreach-parameter~opt~ new-lines~opt~
        ( new-lines~opt~ variable new-lines~opt~ *in* new-lines~opt~ pipeline
        new-lines~opt~ ) statement-block

foreach-parameter:
    -parallel

Beschrijving:

De lustekst, die bestaat uit instructieblok, wordt uitgevoerd voor elk element dat is aangewezen door de variabele variabele in de verzameling die is aangewezen door de pijplijn. Het bereik van de variabele is niet beperkt tot de foreach-instructie. Als zodanig behoudt het de uiteindelijke waarde nadat de hoofdtekst van de lus is voltooid. Als een pijplijn een scalaire waarde aanwijst (met uitzondering van de waarde $null) in plaats van een verzameling, wordt die scalaire waarde beschouwd als een verzameling van één element. Als de pijplijn de waarde $nullaanwijst, wordt de pijplijn behandeld als een verzameling nulelementen.

Als de foreach-parameter -parallel is opgegeven, wordt het gedrag gedefinieerd.

De foreach-parameter ‑parallel is alleen toegestaan in een werkstroom (§8.10.2).

Elke foreach-instructie heeft een eigen enumerator, $foreach (§2.3.2.2, §4.5.16), die alleen bestaat terwijl die lus wordt uitgevoerd.

De objecten die door de pijplijn worden geproduceerd, worden verzameld voordat het instructieblok wordt uitgevoerd. Met de ForEach-Object-cmdlet wordt instructieblok echter uitgevoerd op elk object zoals het wordt geproduceerd.

Voorbeelden:

$a = 10, 53, 16, -43
foreach ($e in $a) {
    ...
}
$e # the int value -43

foreach ($e in -5..5) {
    ...
}

foreach ($t in [byte], [int], [long]) {
    $t::MaxValue # get static property
}

foreach ($f in Get-ChildItem *.txt) {
    ...
}

$h1 = @{ FirstName = "James"; LastName = "Anderson"; IDNum = 123 }
foreach ($e in $h1.Keys) {
    "Key is " + $e + ", Value is " + $h1[$e]
}

8,5 Flow controle-instructies

Syntaxis:

flow-control-statement:
    break label-expression~opt~
    continue label-expression~opt~
    throw pipeline~opt~
    return pipeline~opt~
    exit pipeline~opt~

label-expression:
    simple-name
    unary-expression

Beschrijving:

Een stroomcontroleverklaring zorgt voor een onvoorwaardelijke overdracht van controle naar een andere locatie.

8.5.1 De onderbrekingsinstructie

Beschrijving:

Een onderbrekingsinstructie met een labelexpressie wordt een gelabelde onderbrekingsinstructie genoemd. Een onderbrekingsinstructie zonder labelexpressie wordt een niet-gelabelde onderbrekingsinstructie genoemd.

Buiten een trapinstructie beëindigt een niet-gelabelde onderbrekingsinstructie rechtstreeks binnen een iteratie-instructie (§8.4) de uitvoering van die kleinste iteratie-instructie. Een niet-gelabelde onderbrekingsinstructie direct binnen een schakelinstructie (§8.6) beëindigt het patroon dat overeenkomt met de schakelvoorwaarde van de huidige switch. Zie (§8.8) voor meer informatie over het gebruik van onderbrekingen vanuit een trapinstructie.

Een iteratie-instructie of een schakelinstructie kan eventueel direct worden voorafgegaan door één instructielabel (§8.1.1). Een dergelijk instructielabel kan worden gebruikt als het doel van een gelabelde onderbrekingsinstructie, in dat geval, die instructie beëindigt de uitvoering van de doelinsluitingsinstructie.

Een gelabeld onderbrekingseinde hoeft niet in een lokaal bereik te worden opgelost; het zoeken naar een overeenkomend label kan doorgaan met de aanroepende stack, zelfs over de grenzen van scripts en functieoproepen. Als er geen overeenkomend label wordt gevonden, wordt de huidige aanroep van de opdracht beëindigd.

De naam van het label dat is aangewezen door labelexpressie , hoeft geen constante waarde te hebben.

Als labelexpressie een unaire expressie is, wordt deze geconverteerd naar een tekenreeks.

Voorbeelden:

$i = 1
while ($true) { # infinite loop
    if ($i * $i -gt 100) {
        break # break out of current while loop
    }
    ++$i
}

$lab = "go_here"
:go_here
for ($i = 1; ; ++$i) {
    if ($i * $i -gt 50) {
        break $lab # use a string value as target
    }
}

:labelA
for ($i = 1; $i -le 2; $i++) {

    :labelB
    for ($j = 1; $j -le 2; $j++) {

        :labelC
        for ($k = 1; $k -le 3; $k++) {
            if (...) { break labelA }
        }
    }
}

8.5.2 De continue instructie

Beschrijving:

Een continue instructie met een labelexpressie wordt een gelabelde continue instructie genoemd. Een continue instructie zonder labelexpressie wordt een niet-gelabelde continue instructie genoemd.

Het gebruik van continue binnen een trap-instructie wordt besproken in §8.8.

Een niet-gelabelde continue instructie binnen een lus beëindigt de uitvoering van de huidige lus en draagt het besturingselement over naar de afsluitende accolade van de kleinste iteratie-instructie (§8.4). Een niet-gelabelde continue instructie binnen een switch beëindigt de uitvoering van de huidige switch iteratie en draagt het besturingselement over naar de kleinste switchschakelvoorwaarde (§8.6).

Een iteratie-instructie of een switch instructie (§8.6) kan eventueel direct worden voorafgegaan door één instructielabel (§8.1.1.1). Een dergelijk instructielabel kan worden gebruikt als het doel van een ingesloten gelabelde continue instructie. In dat geval wordt de uitvoering van de huidige lus of switch iteratie beëindigd en wordt de controle overgedragen naar het betreffende iteratie- of switch instructielabel.

Een gelabeld continue hoeft niet te worden opgelost in een lokaal bereik. Het zoeken naar een overeenkomend label kan continue de aanroepende stack zelfs over de grenzen van scripts en functieoproepen heen. Als er geen overeenkomend label wordt gevonden, wordt de huidige aanroep van de opdracht beëindigd.

De naam van het label dat is aangewezen door labelexpressie , hoeft geen constante waarde te hebben.

Als labelexpressie een unaire expressie is, wordt deze geconverteerd naar een tekenreeks.

Voorbeelden:

$i = 1
while (...) {
    ...
    if (...) {
        continue # start next iteration of current loop
    }
    ...
}

$lab = "go_here"
:go_here
for (...; ...; ...) {
    if (...) {
        continue $lab # start next iteration of labeled loop
    }
}

:labelA
for ($i = 1; $i -le 2; $i++) {

    :labelB
    for ($j = 1; $j -le 2; $j++) {

        :labelC
        for ($k = 1; $k -le 3; $k++) {
            if (...) { continue labelB }
        }
    }
}

8.5.3 De werpinstructie

Beschrijving:

Een uitzondering is een manier om een foutvoorwaarde op systeem- of toepassingsniveau te verwerken. De throw-instructie genereert een uitzondering. (Zie §8.7 voor een bespreking van de verwerking van uitzonderingen.)

Als de pijplijn wordt weggelaten en de throw-instructie zich niet in een catch-component bevindt, wordt het gedrag gedefinieerd. Als de pijplijn aanwezig is en de throw-instructie zich in een catch-component bevindt, wordt de uitzondering die door die catch-component is gevangen, opnieuw gegenereerd nadat een laatste component die is gekoppeld aan de catch-component is uitgevoerd.

Als de pijplijn aanwezig is, wordt het type uitzondering gedefinieerd.

Wanneer er een uitzondering wordt gegenereerd, wordt het besturingselement overgebracht naar de eerste catch-component in een insluitingsinstructie die de uitzondering kan verwerken. De locatie waar de uitzondering in eerste instantie wordt gegenereerd, wordt het gooipunt genoemd. Zodra er een uitzondering wordt gegenereerd, worden de stappen die in §8.7 worden beschreven, herhaaldelijk gevolgd totdat een catch-component die overeenkomt met de uitzondering wordt gevonden of niet kan worden gevonden.

Voorbeelden:

throw
throw 100
throw "No such record in file"

Als de pijplijn wordt weggelaten en de instructie throw niet afkomstig is van een catch-component, wordt de tekst ScriptHalted naar de pijplijn geschreven en wordt het type uitzondering gegenereerd System.Management.Automation.RuntimeException.

Als de pijplijn aanwezig is, wordt de gegenereerde uitzondering verpakt in een object van het type System.Management.Automation.RuntimeException, dat informatie bevat over de uitzondering als een System.Management.Automation.ErrorRecord object (toegankelijk via $_).

Voorbeeld 1: throw 123 resulteert in een uitzondering van het type RuntimeException. Vanuit het catch-blok $_.TargetObject bevat het object dat binnen is verpakt, in dit geval een System.Int32 met waarde 123.

Voorbeeld 2: throw "xxx" resulteert in een uitzondering van het type RuntimeException. Vanuit het catch-blok $_.TargetObject bevat het object dat in dit geval is verpakt, een System.String met de waarde xxx.

Voorbeeld 3: throw 10,20 resulteert in een uitzondering van het type RuntimeException. Vanuit het catch-blok $_.TargetObject bevat het object dat binnen is verpakt, in dit geval een , een System.Object[]niet-getrainde matrix van twee elementen met de System. Int32' waarden 10 en 20.

8.5.4 De retourinstructie

Beschrijving:

De return instructie schrijft naar de pijplijn de waarde(s) die zijn aangewezen door de pijplijn, indien van toepassing, en retourneert het besturingselement naar de aanroeper van de functie of het script. Een functie of script kan nul of meer return instructies bevatten.

Als de uitvoering de afsluitende accolade van een functie bereikt, wordt ervan uitgegaan dat een functie wordt geïmpliceerd return zonder pijplijn .

De return instructie is een beetje 'syntactische suiker' zodat programmeurs zichzelf kunnen uitdrukken zoals ze in andere talen kunnen. De waarde die wordt geretourneerd van een functie of script is echter eigenlijk alle waarden die door die functie of script naar de pijplijn zijn geschreven, plus waarde(s) die zijn opgegeven door de pijplijn. Als alleen een scalaire waarde naar de pijplijn wordt geschreven, is het bijbehorende type het type van de geretourneerde waarde; anders is het retourtype een niet-gekoppelde 1-dimensionale matrix die alle waarden bevat die naar de pijplijn zijn geschreven.

Voorbeelden:

function Get-Factorial ($v) {
    if ($v -eq 1) {
        return 1 # return is not optional
    }

    return $v * (Get-Factorial ($v - 1)) # return is optional
}

De beller om Get-Factorial een int.

function Test {
    "text1" # "text1" is written to the pipeline
    # ...
    "text2" # "text2" is written to the pipeline
    # ...
    return 123 # 123 is written to the pipeline
}

De aanroeper om een ongeconstrainde 1dimensionale matrix van drie elementen terug te Test halen.

8.5.5 De afsluitinstructie

Beschrijving:

De afsluitinstructie beëindigt het huidige script en retourneert controle en een afsluitcode naar de hostomgeving of het aanroepende script. Als er een pijplijn wordt opgegeven, wordt de waarde die deze aanwijst, indien nodig geconverteerd naar int. Als er geen dergelijke conversie bestaat of als pijplijn wordt weggelaten, wordt de int-waarde nul geretourneerd.

Voorbeelden:

exit $count # terminate the script with some accumulated count

8.6 De schakelinstructie

Syntaxis:

switch-statement:
    switch new-lines~opt~ switch-parameters~opt~ switch-condition switch-body

switch-parameters:
    switch-parameter
    switch-parameters switch-parameter

switch-parameter:
    -regex
    -wildcard
    -exact
    -casesensitive
    -parallel

switch-condition:
    ( new-lines~opt~ pipeline new-lines~opt~ )
    -file new-lines~opt~ switch-filename

switch-filename:
    command-argument
    primary-expression

switch-body:
    new-lines~opt~ { new-lines~opt~ switch-clauses }

switch-clauses:
    switch-clause
    switch-clauses switch-clause

switch-clause:
    switch-clause-condition statement-block statement-terimators~opt~

switch-clause-condition:
    command-argument
    primary-expression

Beschrijving:

Als een schakelvoorwaarde één waarde aanwijst, wordt het besturingselement doorgegeven aan een of meer overeenkomende patrooninstructieblokken. Als er geen patronen overeenkomen, kan er een aantal standaardacties worden uitgevoerd.

Een switch moet een of meer schakelclausules bevatten, elk beginnend met een patroon (een niet-standaardswitchcomponent) of het trefwoord default (een standaardswitchcomponent). Een switch moet nul- of één default switchcomponent bevatten en nul of meer niet-standaardswitchclausules. Schakelclausules kunnen in elke volgorde worden geschreven.

Meerdere patronen kunnen dezelfde waarde hebben. Een patroon hoeft niet letterlijk te zijn en een switch kan patronen met verschillende typen hebben.

Als de waarde van een schakelvoorwaarde overeenkomt met een patroonwaarde, wordt het instructieblok van dat patroon uitgevoerd. Als meerdere patroonwaarden overeenkomen met de waarde van een schakelvoorwaarde, wordt het instructieblok van elk overeenkomend patroon in lexicale volgorde uitgevoerd, tenzij een van deze instructieblokken een break instructie bevat (§8.5.1).

Als de waarde van een schakelvoorwaarde niet overeenkomt met een patroonwaarde, wordt het instructieblok uitgevoerd als er een default switchcomponent bestaat. Anders wordt patroonkoppeling voor die schakelvoorwaarde beëindigd.

Schakelopties kunnen worden genest, waarbij elke switch een eigen set switchcomponenten heeft. In dergelijke gevallen behoort een switchcomponent tot de binnenste switch die momenteel binnen het bereik valt.

Bij het invoeren van elk instructieblok wordt $_ automatisch de waarde van de schakelvoorwaarde toegewezen waardoor het besturingselement naar dat instructieblok is gegaan. $_is ook beschikbaar in de switch-component-condition van dat instructieblok.

Het vergelijken van niet-tekenreeksen wordt uitgevoerd door te testen op gelijkheid (§7.8.1).

Als de overeenkomst tekenreeksen omvat, is de vergelijking standaard niet hoofdlettergevoelig. De aanwezigheid van de schakelparameter -casesensitive maakt de vergelijking hoofdlettergevoelig.

Een patroon kan jokertekens bevatten (§3.15), in dat geval worden vergelijkingen van jokertekenreeksen uitgevoerd, maar alleen als de switch-parameter -jokerteken aanwezig is. De vergelijking is standaard niet hoofdlettergevoelig.

Een patroon kan een reguliere expressie (§3.16) bevatten. In dat geval worden reguliere expressiereeksvergelijkingen uitgevoerd, maar alleen als de switch-parameter -regex aanwezig is. De vergelijking is standaard niet hoofdlettergevoelig. Als -regex er een patroon aanwezig is en een patroon overeenkomt, $matches wordt gedefinieerd in het instructieblok switch-component voor dat patroon.

Een schakelparameter kan worden afgekort; elk afzonderlijk voorloopgedeelte van een parameter kan worden gebruikt. Bijvoorbeeld, ‑regex``‑rege, ‑reg, , ‑reen ‑r zijn equivalent.

Als conflicterende switchparameter s worden opgegeven, wordt de lexicale laatste opgegeven. De aanwezigheid van ‑exact uitschakelen -regex en -wildcard; het heeft echter geen invloed op ‑case.

Als de switchparameter ‑parallel is opgegeven, wordt het gedrag gedefinieerd.

De schakelparameter ‑parallel is alleen toegestaan in een werkstroom (§8.10.2).

Als een patroon een scriptblokexpressie is, wordt dat blok geëvalueerd en wordt het resultaat indien nodig geconverteerd naar bool. Als het resultaat de waarde $trueheeft, wordt het bijbehorende instructieblok uitgevoerd; anders niet.

Als een schakelvoorwaarde meerdere waarden aanwijst, wordt de schakeloptie toegepast op elke waarde in lexicale volgorde met behulp van de regels die hierboven worden beschreven voor een schakelvoorwaarde die één waarde aanwijst. Elke switch-instructie heeft een eigen enumerator($switch§2.3.2.2, §4.5.16), die alleen bestaat terwijl die switch wordt uitgevoerd.

Een switch-instructie kan een label bevatten en kan een gelabelde en niet-gelabelde onderbreking (§8.5.1) bevatten en doorgaan (§8.5.2) instructies.

Als de schakelvoorwaarde de switch-bestandsnaam is-file, in plaats van de waarden in een expressie te herhalen, wordt de schakeloptie herhaald over de waarden in het bestand dat is aangewezen door de switch-bestandsnaam. Het bestand leest een regel tegelijk met elke regel die een waarde bevat. Regeleindtekens worden niet opgenomen in de waarden.

Voorbeelden:

$s = "ABC def`nghi`tjkl`fmno @#$"
$charCount = 0; $pageCount = 0; $lineCount = 0; $otherCount = 0
for ($i = 0; $i -lt $s.Length; ++$i) {
    ++$charCount
    switch ($s[$i]) {
        "`n" { ++$lineCount }
        "`f" { ++$pageCount }
        "`t" { }
        " " { }
        default { ++$otherCount }
    }
}

switch -wildcard ("abc") {
    a* { "a*, $_" }
    ?B? { "?B? , $_" }
    default { "default, $_" }
}

switch -regex -casesensitive ("abc") {
    ^a* { "a*" }
    ^A* { "A*" }
}

switch (0, 1, 19, 20, 21) {
    { $_ -lt 20 } { "-lt 20" }
    { $_ -band 1 } { "Odd" }
    { $_ -eq 19 } { "-eq 19" }
    default { "default" }
}

8.7 De instructie try/finally

Syntaxis:

try-statement:
    try statement-block catch-clauses
    try statement-block finally-clause
    try statement-block catch-clauses finally-clause

catch-clauses:
    catch-clause
    catch-clauses catch-clause

catch-clause:
    new-lines~opt~ catch catch-type-list~opt~
    statement-block

catch-type-list:
    new-lines~opt~ type-literal
    catch-type-list new-lines~opt~ , new-lines~opt~

type-literalfinally-clause:
    new-lines~opt~ finally statement-block

Beschrijving:

De try-instructie biedt een mechanisme voor het vangen van uitzonderingen die optreden tijdens het uitvoeren van een blok. De try-instructie biedt ook de mogelijkheid om een blok code op te geven dat altijd wordt uitgevoerd wanneer het besturingselement de try-instructie verlaat. Het proces voor het indienen van een uitzondering via de instructie throw wordt beschreven in §8.5.3.

Een try-blok is het instructieblok dat is gekoppeld aan de try-instructie . Een catch-blok is het instructieblok dat is gekoppeld aan een catch-component. Een laatste blok is het instructieblok dat is gekoppeld aan een definitieve component.

Een catch-component zonder een catch-type-list wordt een algemene catch-component genoemd.

Elke catch-component is een uitzonderingshandler en een catch-component waarvan de catch-type-list het type van de gegenereerde uitzondering bevat, is een overeenkomende catch-component. Een algemene catch-component komt overeen met alle uitzonderingstypen.

Hoewel catch-components en definitief component optioneel zijn, moet er ten minste één van deze componenten aanwezig zijn.

De verwerking van een gegenereerde uitzondering bestaat uit het herhaaldelijk evalueren van de volgende stappen totdat een catch-component die overeenkomt met de uitzondering wordt gevonden.

  • In het huidige bereik wordt elke try-instructie die het gooipunt omsluit, onderzocht. Voor elke try-instructie S, beginnend met de binnenste try-instructie en eindigend met de buitenste try-instructie, worden de volgende stappen geëvalueerd:

    • Als het blok S het try gooipunt omsluit en als S een of meer catch-componenten heeft, worden de catch-componenten in lexicale volgorde onderzocht om een geschikte handler voor de uitzondering te vinden. De eerste catch-component waarmee het uitzonderingstype of een basistype van het uitzonderingstype wordt opgegeven, wordt beschouwd als een overeenkomst. Een algemene catch-component wordt beschouwd als een overeenkomst voor elk uitzonderingstype. Als een overeenkomende catch-component zich bevindt, wordt de uitzonderingsverwerking voltooid door het besturingselement over te dragen naar het blok van die catch-component. Binnen een overeenkomende catch-component bevat de variabele $_ een beschrijving van de huidige uitzondering.

    • Als het try blok of een catch blok S het gooipunt omsluit en als S een finally blok heeft, wordt het besturingselement overgezet naar het laatste blok. Als het finally blok een andere uitzondering genereert, wordt de verwerking van de huidige uitzondering beëindigd. Anders wordt de verwerking van de huidige uitzondering voortgezet wanneer het besturingselement het einde van het finally blok bereikt.

  • Als een uitzonderingshandler zich niet in het huidige bereik bevindt, worden de bovenstaande stappen vervolgens herhaald voor het insluitbereik met een werppunt dat overeenkomt met de instructie waaruit het huidige bereik is aangeroepen.

  • Als de uitzonderingsverwerking alle bereiken beëindigt, geeft u aan dat er geen handler bestaat voor de uitzondering, dan is het gedrag niet opgegeven.

Als u onbereikbare catch-componenten in een try-blok wilt voorkomen, geeft een catch-component mogelijk geen uitzonderingstype op dat gelijk is aan of is afgeleid van een type dat is opgegeven in een eerdere catch-component binnen datzelfde try-blok.

De instructies van een finally blok worden altijd uitgevoerd wanneer het besturingselement een try instructie verlaat. Dit is waar of de controleoverdracht plaatsvindt als gevolg van normale uitvoering, als gevolg van het uitvoeren van een break, continueof instructie, of return als gevolg van een uitzondering die uit de try instructie wordt gegenereerd.

Als er een uitzondering wordt gegenereerd tijdens het uitvoeren van een finally blok, wordt de uitzondering naar de volgende insluitinstructie try gegenereerd. Als er een andere uitzondering is opgetreden bij het verwerken van deze uitzondering, gaat deze uitzondering verloren. Het proces voor het genereren van een uitzondering wordt verder besproken in de beschrijving van de throw instructie.

try instructies kunnen naast instructies bestaan trap . Zie §8.8 voor meer informatie.

Voorbeelden:

$a = new-object 'int[]' 10
$i = 20 # out-of-bounds subscript

while ($true) {
    try {
        $a[$i] = 10
        "Assignment completed without error"
        break
    }

    catch [IndexOutOfRangeException] {
        "Handling out-of-bounds index, >$_<`n"
        $i = 5
    }

    catch {
        "Caught unexpected exception"
    }

    finally {
        # ...
    }
}

Elke gegenereerde uitzondering wordt als een System.Management.Automation.RuntimeException. Als er typespecifieke catch-components in het try blok staan, wordt de eigenschap InnerException van de uitzondering geïnspecteerd om te proberen een overeenkomst te vinden, zoals met het bovenstaande type System.IndexOutOfRangeException .

8.8 De trapinstructie

Syntaxis:

trap-statement:
    *trap* new-lines~opt~ type-literal~opt~ new-lines~opt~ statement-block

Beschrijving:

Een trap instructie met en zonder type-letterlijk is vergelijkbaar met een catch blok (§8.7) met respectievelijk en zonder catch-type-list, behalve dat een trap instructie slechts één type tegelijk kan vangen.

Meerdere trap instructies kunnen worden gedefinieerd in hetzelfde instructieblok en de volgorde van de definitie is irrelevant. Als twee trap instructies met dezelfde type-letterlijke waarde in hetzelfde bereik worden gedefinieerd, wordt de lexicatische eerste gebruikt om een uitzondering van het overeenkomende type te verwerken.

In tegenstelling tot een catch blok komt een trap instructie exact overeen met een uitzonderingstype. Er wordt geen overeenkomend type afgeleid uitgevoerd.

Wanneer er een uitzondering optreedt, als er geen overeenkomende trap instructie aanwezig is in het huidige bereik, wordt er gezocht naar een overeenkomende trap-instructie in het bereik waarin het aanroepende script, de functie of het filter wordt gebruikt, enzovoort. Als de zoekactie alle bereiken beëindigt, geeft u aan dat er geen handler bestaat voor de uitzondering, dan is het gedrag niet opgegeven.

De instructietekst van een trap instructie wordt alleen uitgevoerd om de bijbehorende uitzondering te verwerken. Anders wordt de uitvoering doorgegeven.

Als de trapinstructietekst normaal wordt afgesloten, wordt standaard een foutobject naar de foutstroom geschreven, wordt de uitzondering beschouwd als verwerkt en wordt de uitvoering voortgezet met de instructie direct na de instructie in het bereik met de trap instructie die de uitzondering zichtbaar maakte. De oorzaak van de uitzondering kan zich in een opdracht bevinden die wordt aangeroepen door de opdracht die de trap instructie bevat.

Als de laatste instructie die wordt uitgevoerd in de trapinstructietekst wordt voortgezet (§8.5.2), wordt het schrijven van het foutobject naar de foutstroom onderdrukt en wordt de uitvoering voortgezet met de instructie direct na de instructie in het bereik met de trapinstructie die de uitzondering zichtbaar maakte. Als de laatste instructie die wordt uitgevoerd in de instructietekst van de trapinstructie is verbroken (§8.5.1), wordt het schrijven van het foutobject naar de foutstroom onderdrukt en wordt de uitzondering opnieuw gegenereerd.

Binnen een trap instructie bevat de variabele $_ een beschrijving van de huidige fout.

Houd rekening met het geval waarin een uitzondering die vanuit een try blok wordt gegenereerd, geen overeenkomend blok heeft, maar dat er een overeenkomende catch trap instructie bestaat op een hoger blokniveau. Nadat de laatste component van het try blok is uitgevoerd, krijgt de trap instructie controle, zelfs als een bovenliggend bereik een overeenkomend catch blok heeft. Als een trap instructie in het try blok zelf is gedefinieerd en dat try blok een overeenkomend catch blok heeft, krijgt de trap instructie controle.

Voorbeelden:

In het volgende voorbeeld wordt het foutobject geschreven en wordt de uitvoering voortgezet met de instructie direct na de instructie die de trap heeft veroorzaakt; 'Gereed' wordt naar de pijplijn geschreven.

$j = 0; $v = 10/$j; "Done"
trap { $j = 2 }

In het volgende voorbeeld wordt het schrijven van het foutobject onderdrukt en wordt de uitvoering voortgezet met de instructie direct na de instructie die de trap heeft veroorzaakt; 'Gereed' wordt naar de pijplijn geschreven.

$j = 0; $v = 10/$j; "Done"
trap { $j = 2; continue }

In het volgende voorbeeld wordt het schrijven van het foutobject onderdrukt en wordt de uitzondering opnieuw gegenereerd.

$j = 0; $v = 10/$j; "Done"
trap { $j = 2; break }

In het volgende voorbeeld bevinden de trap- en uitzonderings genererende instructies zich in hetzelfde bereik. Nadat de uitzondering is opgepakt en verwerkt, wordt de uitvoering hervat met het schrijven van 1 naar de pijplijn.

&{trap{}; throw '\...'; 1}

In het volgende voorbeeld bevinden de trap- en uitzonderings genererende instructies zich in verschillende bereiken. Nadat de uitzondering is opgepakt en verwerkt, wordt de uitvoering hervat met het schrijven van 2 (niet 1) naar de pijplijn.

trap{} &{throw '\...'; 1}; 2

8.9 De gegevensinstructie

Syntaxis:

data-statement:
    data new-lines~opt~ data-name data-commands-allowed~opt~ statement-block

data-name:
    simple-name

data-commands-allowed:
    new-lines~opt~ -supportedcommand data-commands-list

data-commands-list:
    new-lines~opt~ data-command
    data-commands-list , new-lines~opt~ data-command

data-command:
    command-name-expr

Beschrijving:

Een gegevensinstructie maakt een gegevenssectie, waardoor de gegevens van die sectie gescheiden blijven van de code. Deze scheiding ondersteunt faciliteiten zoals afzonderlijke tekenreeksresourcebestanden voor tekst, zoals foutberichten en Help-tekenreeksen. Het helpt ook internationalisatie te ondersteunen door tekenreeksen te isoleren, te zoeken en te verwerken die in verschillende talen worden vertaald.

Een script of functie kan nul of meer gegevenssecties bevatten.

Het instructieblok van een gegevenssectie is beperkt tot alleen de volgende PowerShell-functies:

  • Alle operators behalve -match
  • De if instructie
  • De volgende automatische variabelen: $PsCulture, $PsUICulture, $true, $falseen $null.
  • Opmerkingen
  • Pipelines
  • Instructies gescheiden door puntkomma's (;)
  • Literals
  • Aanroepen naar de cmdlet ConvertFrom-StringData
  • Andere cmdlets die worden geïdentificeerd via de ondersteunde parameter

Als de ConvertFrom-StringData cmdlet wordt gebruikt, kunnen de sleutel-/waardeparen worden uitgedrukt met behulp van elke vorm van letterlijke tekenreeks. Expandable-string-literal s en expandable-here-string-literal s mogen echter geen variabele vervangingen of subexpressie-uitbreidingen bevatten.

Voorbeelden:

De parameter SupportedCommand geeft aan dat de opgegeven cmdlets of functies alleen gegevens genereren. De volgende gegevenssectie bevat bijvoorbeeld een door de gebruiker geschreven cmdlet, ConvertTo-XMLwaarmee gegevens in een XML-bestand worden opgemaakt:

data -supportedCommand ConvertTo-XML {
    Format-XML -strings string1, string2, string3
}

Bekijk het volgende voorbeeld, waarin de gegevenssectie een ConvertFrom-StringData opdracht bevat waarmee de tekenreeksen worden geconverteerd naar een hash-tabel, waarvan de waarde is toegewezen aan $messages.

$messages = data {
    ConvertFrom-StringData -stringdata @'
    Greeting = Hello
    Yes = yes
    No = no
'@
}

De sleutels en waarden van de hash-tabel worden geopend met respectievelijk $messages.Greeting``$messages.Yes, en $messages.No.

Dit kan nu worden opgeslagen als een Engelstalige resource. Duits- en Spaanstalige resources kunnen worden gemaakt in afzonderlijke bestanden, met de volgende gegevenssecties:

$messages = data {
    ConvertFrom-StringData -stringdata @"
    Greeting = Guten Tag
    Yes = ja
    No = nein
"@
}

$messagesS = data {
    ConvertFrom-StringData -stringdata @"
    Greeting = Buenos días
    Yes = sí
    No = no
"@
}

Als de gegevensnaam aanwezig is, wordt de variabele (zonder een voorloop $) aangeduid waarin de waarde van de gegevensinstructie moet worden opgeslagen. Specifiek, $name = data { ... } is gelijk aan data name { ... }.

8.10 Functiedefinities

Syntaxis:

function-statement:
    function new-lines~opt~ function-name function-parameter-declaration~opt~ { script-block }
    filter new-lines~opt~ function-name function-parameter-declaration~opt~ { script-block }
    workflow new-lines~opt~ function-name function-parameter-declaration~opt~ { script-block }

function-name:
    command-argument

command-argument:
    command-name-expr

function-parameter-declaration:
    new-lines~opt~ ( parameter-list new-lines~opt~ )

parameter-list:
    script-parameter
    parameter-list new-lines~opt~ , script-parameter

script-parameter:
    new-lines~opt~ attribute-list~opt~ new-lines~opt~ variable script-parameter-default~opt~

script-block:
    param-block~opt~ statement-terminators~opt~ script-block-body~opt~

param-block:
    new-lines~opt~ attribute-list~opt~ new-lines~opt~ param new-lines~opt~
        ( parameter-list~opt~ new-lines~opt~ )

parameter-list:
    script-parameter
    parameter-list new-lines~opt~ , script-parameter

script-parameter-default:
    new-lines~opt~ = new-lines~opt~ expression

script-block-body:
    named-block-list
    statement-list

named-block-list:
    named-block
    named-block-list named-block

named-block:
    block-name statement-block statement-terminators~opt~

block-name: one of
    dynamicparam   begin   process   end

Beschrijving:

Een functiedefinitie geeft de naam op van de functie, het filter of de werkstroom die wordt gedefinieerd en de namen van de parameters, indien van toepassing. Het bevat ook nul of meer instructies die worden uitgevoerd om het doel van die functie te bereiken.

Elke functie is een exemplaar van de klasse System.Management.Automation.FunctionInfo.

8.10.1 Filterfuncties

Terwijl een gewone functie eenmaal in een pijplijn wordt uitgevoerd en de invoerverzameling opent via $input, is een filter een speciaal soort functie die eenmaal wordt uitgevoerd voor elk object in de invoerverzameling. Het object dat momenteel wordt verwerkt, is beschikbaar via de variabele $_.

Een filter zonder benoemde blokken (§8.10.7) is gelijk aan een functie met een procesblok, maar zonder beginblok of eindblok.

Houd rekening met de volgende filterfunctiedefinitie en aanroepen:

filter Get-Square2 { # make the function a filter
    $_ * $_ # access current object from the collection
}

-3..3 | Get-Square2 # collection has 7 elements
6, 10, -3 | Get-Square2 # collection has 3 elements

Elk filter is een exemplaar van de klasse System.Management.Automation.FilterInfo (§4.5.11).

8.10.2 Werkstroomfuncties

Een werkstroomfunctie is net als een gewone functie met door de implementatie gedefinieerde semantiek. Een werkstroomfunctie wordt omgezet in een reeks Windows Workflow Foundation-activiteiten en uitgevoerd in de Windows Workflow Foundation-engine.

8.10.3 Argumentverwerking

Houd rekening met de volgende definitie voor een functie met de naam Get-Power:

function Get-Power ([long]$base, [int]$exponent) {
    $result = 1
    for ($i = 1; $i -le $exponent; ++$i) {
        $result *= $base
    }
    return $result
}

Deze functie heeft twee parameters en $base $exponent. Het bevat ook een set instructies die, voor niet-negatieve exponentwaarden, berekent en retourneert $base^$exponent^ het resultaat naar Get-Powerde aanroeper.

Wanneer een script, functie of filter wordt uitgevoerd, wordt elke parameter geïnitialiseerd op de bijbehorende waarde van het argument. Als er geen corresponderend argument is en er een standaardwaarde (§8.10.4) wordt opgegeven, wordt die waarde gebruikt; anders wordt de waarde $null gebruikt. Daarom is elke parameter een nieuwe variabele, net als als deze is geïnitialiseerd door toewijzing aan het begin van het scriptblok.

Als een scriptparameter een typebeperking bevat (zoals [long] en [int] hoger), wordt de waarde van het bijbehorende argument, indien nodig, geconverteerd naar dat type. Anders treedt er geen conversie op.

Wanneer een script, functie of filter wordt uitgevoerd, wordt de variabele $args erin gedefinieerd als een ongeconstrainde 1dimensionale matrix, die alle argumenten bevat die niet zijn gebonden aan naam of positie, in lexicale volgorde.

Houd rekening met de volgende functiedefinitie en aanroepen:

function F ($a, $b, $c, $d) { ... }

F -b 3 -d 5 2 4       # $a is 2, $b is 3, $c is 4, $d is 5, $args Length 0
F -a 2 -d 3 4 5       # $a is 2, $b is 4, $c is 5, $d is 3, $args Length 0
F 2 3 4 5 -c 7 -a 1   # $a is 1, $b is 2, $c is 7, $d is 3, $args Length 2

Zie §8.14 voor meer informatie over parameterbinding.

8.10.4 Parameter initializers

De declaratie van een parameter p kan een initialisatiefunctie bevatten, in welk geval de waarde van de initialisatiefunctie wordt gebruikt om p op voorwaarde p te initialiseren, is niet gebonden aan argumenten in de aanroep.

Houd rekening met de volgende functiedefinitie en aanroepen:

function Find-Str ([string]$str, [int]$start_pos = 0) { ... }

Find-Str "abcabc" # 2nd argument omitted, 0 used for $start_pos
Find-Str "abcabc" 2 # 2nd argument present, so it is used for $start_pos

8.10.5 De typebeperking [switch]

Wanneer een switchparameter wordt doorgegeven, moet de bijbehorende parameter in de opdracht worden beperkt door de typeswitch. Typeschakelaar heeft twee waarden, Waar en Onwaar.

Houd rekening met de volgende functiedefinitie en aanroepen:

function Process ([switch]$trace, $p1, $p2) { ... }

Process 10 20                # $trace is False, $p1 is 10, $p2 is 20
Process 10 -trace 20         # $trace is True, $p1 is 10, $p2 is 20
Process 10 20 -trace         # $trace is True, $p1 is 10, $p2 is 20
Process 10 20 -trace:$false  # $trace is False, $p1 is 10, $p2 is 20
Process 10 20 -trace:$true   # $trace is True, $p1 is 10, $p2 is 20

8.10.6 Pijplijnen en functies

Wanneer een script, functie of filter wordt gebruikt in een pijplijn, wordt er een verzameling waarden aan dat script of die functie geleverd. Het script, de functie of het filter krijgt toegang tot die verzameling via de enumerator $input (§2.3.2.2, §4.5.16), die is gedefinieerd bij het invoeren van dat script, de functie of het filter.

Houd rekening met de volgende functiedefinitie en aanroepen:

function Get-Square1 {
    foreach ($i in $input) {   # iterate over the collection
        $i * $i
    }
}

-3..3 | Get-Square1            # collection has 7 elements
6, 10, -3 | Get-Square1        # collection has 3 elements

8.10.7 Benoemde blokken

De instructies in een scriptblok kunnen deel uitmaken van een groot, niet-benoemd blok of kunnen worden gedistribueerd naar een of meer benoemde blokken. Benoemde blokken maken aangepaste verwerking van verzamelingen mogelijk die afkomstig zijn van pijplijnen; benoemde blokken kunnen in elke volgorde worden gedefinieerd.

De instructies in een beginblok (d.w.w.v. één gemarkeerd met het trefwoord begin) worden eenmaal uitgevoerd voordat het eerste pijplijnobject wordt geleverd.

De instructies in een procesblok (bijvoorbeeld één die is gemarkeerd met het trefwoordproces) worden uitgevoerd voor elk pijplijnobject dat wordt geleverd. ($_ biedt toegang tot het huidige object dat wordt verwerkt vanuit de invoerverzameling die afkomstig is van de pijplijn.) Dit betekent dat als een verzameling nulelementen via de pijplijn wordt verzonden, het procesblok helemaal niet wordt uitgevoerd. Als het script of de functie echter buiten een pijplijncontext wordt aangeroepen, wordt dit blok precies één keer uitgevoerd en $_ ingesteld $nullop , omdat er geen huidig verzamelingsobject is.

De instructies in een eindblok (d.w.w.v. één gemarkeerd met het trefwoordeinde) worden eenmaal uitgevoerd nadat het laatste pijplijnobject is geleverd.

8.10.8 dynamicParam blok

De subsecties van §8.10 hebben tot nu toe betrekking op statische parameters, die zijn gedefinieerd als onderdeel van de broncode. Het is ook mogelijk om dynamische parameters te definiëren via een dynamicParam-blok, een andere vorm van benoemd blok (§8.10.7), dat is gemarkeerd met het trefwoord dynamicParam. Veel van deze machines zijn gedefinieerd.

Dynamische parameters zijn parameters van een cmdlet, functie, filter of script die alleen onder bepaalde voorwaarden beschikbaar zijn. Een dergelijk geval is de coderingsparameter van de Set-Item cmdlet.

Gebruik in het instructieblok een if-instructie om de voorwaarden op te geven waaronder de parameter beschikbaar is in de functie. Gebruik de cmdlet New-Object om een object van een door de implementatie gedefinieerd type te maken om de parameter weer te geven en geef de naam op. Gebruik New-Object ook om een object van een ander door de implementatie gedefinieerd type te maken om de door de implementatie gedefinieerde kenmerken van de parameter weer te geven.

In het volgende voorbeeld ziet u een functie met standaardparameters genaamd Naam en Pad en een optionele dynamische parameter met de naam DP1. De DP1-parameter bevindt zich in de PSet1-parameterset en heeft een type Int32. De DP1-parameter is alleen beschikbaar in de voorbeeldfunctie wanneer de waarde van de parameter Path 'HKLM:' bevat, waarmee wordt aangegeven dat deze wordt gebruikt in het HKEY_LOCAL_MACHINE registerstation.

function Sample {
    Param ([String]$Name, [String]$Path)
    DynamicParam {
        if ($path -match "*HKLM*:") {
            $dynParam1 = New-Object System.Management.Automation.RuntimeDefinedParameter("dp1", [Int32], $attributeCollection)

            $attributes = New-Object System.Management.Automation.ParameterAttribute
            $attributes.ParameterSetName = 'pset1'
            $attributes.Mandatory = $false

            $attributeCollection = New-Object -Type System.Collections.ObjectModel.Collection``1[System.Attribute]
            $attributeCollection.Add($attributes)

            $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary
            $paramDictionary.Add("dp1", $dynParam1)
            return $paramDictionary
        }
    }
}

Het type dat wordt gebruikt om een object te maken dat een dynamische parameter vertegenwoordigt, is System.Management.Automation.RuntimeDefinedParameter.

Het type dat wordt gebruikt om een object te maken dat de kenmerken van de parameter vertegenwoordigt, is System.Management.Automation.ParameterAttribute.

De door de implementatie gedefinieerde kenmerken van de parameter omvatten Verplicht, Positie en ValueFromPipeline.

8.10.9 param blok

Een param-blok biedt een alternatieve manier om parameters te declareren. De volgende sets parameterdeclaraties zijn bijvoorbeeld gelijkwaardig:

function FindStr1 ([string]$str, [int]$start_pos = 0) { ... }
function FindStr2 {
    param ([string]$str, [int]$start_pos = 0) ...
}

Een param-blok staat een kenmerklijst toe op het param-blok , terwijl een functieparameterdeclaratie dat niet doet.

Een script kan een param-blok hebben, maar geen functieparameterdeclaratie. Een functie- of filterdefinitie kan een functieparameterdeclaratie of een param-blok hebben, maar niet beide.

Kijk eens naar het volgende voorbeeld:

param ( [Parameter(Mandatory = $true, ValueFromPipeline=$true)]
        [string[]] $ComputerName )

De ene parameter, $ComputerNameheeft het type string[], is vereist en neemt invoer uit de pijplijn.

Zie §12.3.7 voor een bespreking van het kenmerk Parameter en voor meer voorbeelden.

8.11 De parallelle instructie

Syntaxis:

parallel-statement:
    *parallel* statement-block

De parallelle instructie bevat nul of meer instructies die op een gedefinieerde manier worden uitgevoerd.

Een parallelle instructie is alleen toegestaan in een werkstroom (§8.10.2).

8.12 De reeksinstructie

Syntaxis:

sequence-statement:
    *sequence* statement-block

De reeksinstructie bevat nul of meer instructies die op een gedefinieerde manier worden uitgevoerd.

Een reeksinstructie is alleen toegestaan in een werkstroom (§8.10.2).

8.13 De inlinescript-instructie

Syntaxis:

inlinescript-statement:
    inlinescript statement-block

De inlinescript-instructie bevat nul of meer instructies die worden uitgevoerd op een gedefinieerde implementatie.

Een inlinescript-instructie is alleen toegestaan in een werkstroom (§8.10.2).

8.14 Parameterbinding

Wanneer een script, functie, filter of cmdlet wordt aangeroepen, kan elk argument worden gebonden aan de bijbehorende parameter op positie, waarbij de eerste parameter positie nul heeft.

Houd rekening met het volgende definitiefragment voor een functie die wordt aangeroepen Get-Poweren de aanroepen ernaar:

function Get-Power ([long]$base, [int]$exponent) { ... }

Get-Power 5 3       # argument 5 is bound to parameter $base in position 0
                    # argument 3 is bound to parameter $exponent in position 1
                    # no conversion is needed, and the result is 5 to the power 3

Get-Power 4.7 3.2   # double argument 4.7 is rounded to int 5, double argument
                    # 3.2 is rounded to int 3, and result is 5 to the power 3

Get-Power 5         # $exponent has value $null, which is converted to int 0

Get-Power           # both parameters have value $null, which is converted to int 0

Wanneer een script, functie, filter of cmdlet wordt aangeroepen, kan een argument worden gebonden aan de bijbehorende parameter op naam. Dit wordt gedaan met behulp van een parameter met argument, een argument dat de naam van de parameter is met een voorloopstreepje (-), gevolgd door de bijbehorende waarde voor dat argument. De gebruikte parameternaam kan elke hoofdlettergevoelige spelling hebben en kan elk voorvoegsel gebruiken dat de bijbehorende parameter uniek aanwijst. Vermijd bij het kiezen van parameternamen de namen van de algemene parameters.

Houd rekening met de volgende aanroepen naar functie Get-Power:

Get-Power -base 5 -exponent 3   # -base designates $base, so 5 is
                                # bound to that, exponent designates
                                # $exponent, so 3 is bound to that

Get-Power -Exp 3 -BAs 5         # $base takes on 5 and $exponent takes on 3

Get-Power -e 3 -b 5             # $base takes on 5 and $exponent takes on 3

Aanroepen naar de volgende functie daarentegen

function Get-Hypot ([double]$side1, [double]$side2) {
    return [Math]::Sqrt($side1 * $side1 + $side2 * $side2)
}

moet parameters -side1 gebruiken en -side2, omdat er geen voorvoegsel is dat de parameter uniek aanwijst.

Dezelfde parameternaam kan niet meerdere keren worden gebruikt met of zonder verschillende gekoppelde argumentwaarden.

Parameters kunnen kenmerken hebben (§12). Zie de secties in §12.3 voor informatie over de afzonderlijke kenmerken. Zie §12.3.7 voor meer informatie over parametersets.

Een script, functie, filter of cmdlet kan argumenten ontvangen via de opdrachtregel voor aanroepen, van de pijplijn of van beide. Hier volgen de stappen, in volgorde, voor het omzetten van parameterbinding:

  1. Alle benoemde parameters binden en vervolgens
  2. Positionele parameters binden en vervolgens
  3. Bind vanuit de pijplijn op waarde (§12.3.7) met exacte overeenkomst en
  4. Bind vanuit de pijplijn op waarde (§12.3.7) met conversie en vervolgens
  5. Bind vanuit de pijplijn op naam (§12.3.7) met exacte overeenkomst en vervolgens
  6. Verbinden vanuit de pijplijn op naam (§12.3.7) met conversie

Een aantal van deze stappen omvat conversie, zoals beschreven in §6. De set conversies die in binding worden gebruikt, is echter niet precies hetzelfde als die in taalconversies. Met name:

  • Hoewel de waarde $null kan worden gecast naar bool, $null kan niet worden gebonden aan bool.
  • Wanneer de waarde $null wordt doorgegeven aan een switchparameter voor een cmdlet, wordt deze behandeld alsof $true deze is doorgegeven. Wanneer echter wordt doorgegeven aan een schakelparameter voor een functie, wordt deze behandeld alsof $false deze is doorgegeven.
  • Parameters van het type bool of schakeloptie kunnen alleen worden gebonden aan numerieke of boolargumenten.
  • Als het parametertype geen verzameling is, maar het argument een soort verzameling is, wordt er geen conversie uitgevoerd, tenzij het parametertype object of PsObject is. (Het belangrijkste punt van deze beperking is het niet toestaan om een verzameling te converteren naar een tekenreeksparameter.) Anders worden de gebruikelijke conversies geprobeerd.

Als het parametertype is IList of ICollection<T>, worden alleen die conversies via constructor, op_Implicit en op_Explicit geprobeerd. Als er geen dergelijke conversies bestaan, wordt er een speciale conversie gebruikt voor parameters van het type verzameling, waaronder IList, ICollection<T>en matrices.

Positionele parameters geven de voorkeur aan afhankelijk te zijn zonder typeconversie, indien mogelijk. Bijvoorbeeld:

function Test {
    [CmdletBinding(DefaultParameterSetname = "SetB")]
    param([Parameter(Position = 0, ParameterSetname = "SetA")]
        [decimal]$dec,
        [Parameter(Position = 0, ParameterSetname = "SetB")]
        [int]$in
    )
    $PsCmdlet.ParameterSetName
}

Test 42d   # outputs "SetA"
Test 42    # outputs "SetB"