8. Utlåtanden

Redaktionell anteckning

Viktigt!

Windows PowerShell Language Specification 3.0 publicerades i december 2012 och baseras på Windows PowerShell 3.0. Den här specifikationen återspeglar inte det aktuella tillståndet för PowerShell. Det finns ingen plan för att uppdatera den här dokumentationen för att återspegla det aktuella tillståndet. Den här dokumentationen presenteras här för historisk referens.

Specifikationsdokumentet är tillgängligt som ett Microsoft Word dokument från Microsoft Download Center på: https://www.microsoft.com/download/details.aspx?id=36389 Det Word dokumentet har konverterats för presentation här på Microsoft Learn. Under konverteringen har vissa redaktionella ändringar gjorts för att anpassa formateringen för Docs-plattformen. Vissa stavfel och mindre fel har korrigerats.

8.1 Utsagningsblock och listor

Syntax:

Tips

Den ~opt~ notationen i syntaxdefinitionerna anger att den lexikala entiteten är valfri i syntaxen.

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

Beskrivning:

En -instruktion anger någon typ av åtgärd som ska utföras. Om inget annat anges i den här klausulen utförs uttrycken i lexikal ordning.

Med ett kan en uppsättning satser grupperas i en enda syntaktisk enhet.

8.1.1 Etiketterade instruktioner

Syntax:

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

Beskrivning:

Ett itereringsuttryck (§8.4) eller en switch-sats (§8.6) kan valfritt föregås direkt av en instruktionsetikett, etikett. En instruktionsetikett används som valfritt mål för en paus (§8.5.1) eller fortsätt (§8.5.2) instruktion. En etikett ändrar dock inte kontrollflödet.

Mellanrum tillåts inte mellan kolonet (:) och det tecken som följer det.

Exempel:

: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 Utsagsvärden

Värdet för ett uttalande är den kumulativa uppsättning värden som det skriver till pipelinen. Om en instruktion skriver ett enda skalärt värde, är det värdet på instruktionen. Om -instruktionen skriver flera värden är värdet för -instruktionen den uppsättning värden som lagras i element i en obehindrat 1-dimensionell matris i den ordning de skrevs. Tänk på följande exempel:

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

Det finns inga iterationer av loopen och ingenting skrivs till pipelinen. Värdet av uttrycket är $null.

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

Även om loopen itererar fem gånger skrivs ingenting till pipelinen. Värdet för utsagan är $null.

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

Loopen itererar fem gånger, och varje gång skriver den värdet av int till pipelinen $i. Värdet av uttrycket är object[] av längd 5.

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

Även om loopen itererar fem gånger skrivs ingenting till pipelinen. Värdet av uttrycket är $null.

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

Loopen itererar fem gånger med varje värde som skrivs till pipelinen. Värdet av uttrycket är object[] av längd 5.

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

Loopen itererar en gång. Värdet för uttalandet är int med värdet 2.

Här är några andra exempel:

# 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 Pipeline-instruktioner

Syntax:

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

Beskrivning:

omdirigeringar diskuteras i §7.12; tilldelningsuttryck diskuteras i §7.11; och kommandoinvokationsoperatorn punkt (.) diskuteras i §3.5.5. En diskussion om argument-till-parameter-mappning i kommandoanrop finns i §8.14.

Det första kommandot i en pipeline är ett uttryck eller ett kommandoanrop. Vanligtvis börjar ett kommandoanrop med ett kommandonamn, vilket oftast är en enkel identifierare. kommandoelement representerar argumentlistan till kommandot. ** En ny rad eller ett okapslat semikolon avslutar en pipeline.

Ett kommandoanrop består av kommandots namn följt av noll eller fler argument. Reglerna som styr argumenten är följande:

  • Ett argument som inte är ett uttryck, men som innehåller godtycklig text utan ej kapslade blanksteg, behandlas som om det vore dubbelt citerat. Brevfallet bevaras.

  • Variabel substitution och expansion av underuttryck (§2.3.5.2) sker inuti expanderbar strängliterals och expandable-here-string-literals.

  • Med text inuti citattecken kan inledande, avslutande och inbäddat tomt utrymme ingå i argumentets värde. [Note: Förekomsten av blanksteg i ett citerat argument omvandlar inte ett enda argument till flera argument. slutkommentar]

  • Om parenteser placeras runt ett argument utvärderas uttrycket med resultatet som skickas i stället för texten i det ursprungliga uttrycket.

  • Om du vill skicka ett argument som ser ut som en [switch] parameter (§2.3.4), men som inte är avsedd som sådan, omsluter du argumentet med citattecken.

  • När du anger ett argument som matchar en parameter som har villkoret [switch] typ (§8.10.5), orsakar förekomsten av argumentnamnet på egen hand att parametern anges till $true. Parameterns värde kan dock anges explicit genom att ett suffix läggs till i argumentet. Om du till exempel anger en typbegränsad parameter panger ett argument för -p:$true p till Sant, medan -p:$false anger p till False.

  • Ett argument med -- anger att alla argument som följer det ska skickas i deras faktiska form som om dubbla citattecken placerades runt dem.

  • Ett argument med --% anger att alla argument som följer ska skickas med minimal parsning och bearbetning. Det här argumentet kallas för den ordagranna parametern. Argument efter den ordagranna parametern är inte PowerShell-uttryck även om de är syntaktiskt giltiga PowerShell-uttryck.

Om kommandotypen är Program skickas inte parametern --% till kommandot. Argument efter --% har några miljövariabler expanderade (omgivna av %strängar). Till exempel:

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

Ordningen för utvärdering av argument är ospecificerad.

Information om parameterbindning finns i §8.14. Information om namnsökning finns i §3.8.

När argumentbearbetningen har slutförts anropas kommandot. Om det anropade kommandot avslutas normalt (§8.5.4) återgår kontrollen till punkten i skriptet eller funktionen omedelbart efter kommandoanropet. En beskrivning av beteendet vid onormal uppsägning finns i break (§8.5.1), continue (§8.5.2), throw (§8.5.3), exit (§8.5.5), try (§8.7), och trap (§8.8).

Normalt anropas ett kommando med hjälp av dess namn följt av eventuella argument. Kommandoanropsoperatorn &kan dock användas. Om kommandonamnet innehåller icke-escapeade blanksteg måste det omges av citattecken och anropas med den här operatorn. Eftersom ett skriptblock inte har något namn måste även det anropas med den här operatorn. Följande anrop av ett kommandoanrop Get-Factorial är till exempel likvärdiga:

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

Direkta och indirekta rekursiva funktionsanrop tillåts. Ett exempel:

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

Exempel:

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 If-instruktionen

Syntax:

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

Beskrivning:

De pipelinekontrolluttryck måste ha typen bool eller vara implicit konvertibla till den typen. else-clause är valfritt. Det kan finnas noll eller fler elseif-clauses.

Om den översta pipelinen testar True körs dess -instruktionsblock och körningen av -instruktionen avslutas. Annars, om en elseif-clause finns, om dess pipeline testar True, körs dess statement-block och körningen av -instruktionen avslutas. Om en else-clause- finns körs annars dess instruktionsblock.

Exempel:

$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 Iterationsinstruktioner

8.4.1 While-instruktionen

Syntax:

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

while-condition:
    new-lines~opt~ pipeline

Beskrivning:

Det kontrollerande uttrycket while-condition måste ha typen bool eller vara implicit konvertibel till den typen. Looptexten, som består av statement-block, körs upprepade gånger tills det kontrollerande uttrycket testar False. Det kontrollerande uttrycket utvärderas före varje körning av looptexten.

Exempel:

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

8.4.2 Do-instruktionen

Syntax:

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

Beskrivning:

Det kontrollerande uttrycket while-condition måste ha typen bool eller vara implicit konvertibel till den typen. I while-formuläret körs looptexten, som består av statement-block, upprepade gånger medan det kontrollerande uttrycket testar Sant. I formuläret till körs looptexten upprepade gånger tills det kontrollerande uttrycket testar True. Det kontrollerande uttrycket utvärderas efter varje körning av looptexten.

Exempel:

$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 For-instruktionen

Syntax:

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

Beskrivning:

Det kontrollerande uttrycket för villkor måste ha typen bool eller vara implicit konvertibel till den typen. Looptexten, som består av statement-block, körs upprepade gånger medan det kontrollerande uttrycket testar Sant. Det kontrollerande uttrycket utvärderas före varje körning av looptexten.

Uttryck for-initializer utvärderas före den första utvärderingen av det kontrollerande uttrycket. Uttryck for-initializer utvärderas endast för dess biverkningar; alla värden som genereras ignoreras och skrivs inte till pipelinen.

Uttryck for-iterator utvärderas efter varje körning av looptexten. Uttryck for-iterator utvärderas endast för dess biverkningar; alla värden som genereras ignoreras och skrivs inte till pipelinen.

Om uttrycket för villkor utelämnas, kommer kontrolluttrycket att utvärderas som Sant.

Exempel:

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 Foreach-instruktionen

Syntax:

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

Beskrivning:

Looptexten, som består av statement-block, körs för varje element som anges av variabeln variabel i samlingen som anges av pipeline. Omfånget för variabel är inte begränsat till foreach-instruktionen. Därför behåller den sitt slutliga värde när looptexten har körts klart. Om pipeline anger en skalär (exklusive värdet $null) i stället för en samling behandlas skalären som en samling med ett element. Om pipeline anger värdet $nullbehandlas pipeline som en samling med nollelement.

Om foreach-parameter-parallel specificeras, definieras beteendet som implementationsberoende.

foreach-parametern‑parallel tillåts endast i ett arbetsflöde (§8.10.2).

Varje foreach-instruktion har sin egen uppräknare, $foreach (§2.3.2.2, §4.5.16), som endast finns medan den slingan körs.

Objekten som skapas av pipeline samlas in innan instruktionsblock börjar köras. Men med cmdleten ForEach-Object körs instruktionsblock på varje objekt när det skapas.

Exempel:

$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 Flödeskontrollinstruktioner

Syntax:

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

Beskrivning:

En flödeskontroll-instruktion orsakar en ovillkorlig överföring av kontroll till någon annan plats.

8.5.1 Break-instruktionen

Beskrivning:

En break-instruktion med ett etikettuttryck kallas för en märkt break-instruktion. En brytinstruktion utan ett etikettuttryck kallas för en oetiketterad brytinstruktion.

Utanför en trap-instruktion avslutar en omärkt break-instruktion direkt inom en iterationsinstruktion (§8.4) körningen av den minsta iterationssatsen. En omärkt brytsats direkt i en switch-instruktion (§8.6) avslutar mönstermatchning för den aktuella växelns switch-condition. Se (§8.8) för information om hur du använder break inifrån en trap-instruktion.

En iterationsinstruktion eller en switch-instruktion kan eventuellt föregås omedelbart av en instruktionsetikett (§8.1.1). En sådan instruktionsetikett kan användas som mål för en märkt break-instruktion, i vilket fall den instruktionen avslutar körningen av den riktade iterationssatsen.

En märkt brytning behöver inte lösas inom något lokalt omfång; sökningen efter en matchande etikett kan fortsätta upp i anropsstacken, även över skript- och funktionsanropsgränser. Om ingen matchande etikett hittas avslutas det aktuella kommandoanropet.

Namnet på etiketten som anges av etikettuttryck behöver inte ha ett konstant värde.

Om etikettuttryck är ett unary-uttryckkonverteras det till en sträng.

Exempel:

$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 Instruktionen Fortsätt

Beskrivning:

En continue-instruktion med ett etikettuttryck kallas för en etiketterad fortsättningsinstruktion. En fortsätt-instruktion utan etikettuttryck kallas för en .

Användningen av continue inifrån en trap-sats beskrivs i §8.8.

En omärkt continue-instruktion inom en loop avslutar exekveringen av den aktuella loopen och överför kontrollen till den avslutande klammerparentesen för den minsta omslutande iterationssatsen (§8.4). En omärkt continue-instruktion inom en växel avslutar körningen av den aktuella switch iterationen och överför kontrollen till den minsta omslutande switch's switch-condition (§8.6).

En iterationsinstruktion eller en switch -instruktion (§8.6) kan eventuellt föregås omedelbart av en instruktionsetikett (§8.1.1). En sådan instruktionsetikett kan användas som mål för en omsluten continue-instruktion med etikett, i vilket fall den instruktionen avslutar körningen av den aktuella loopen eller switch-iterationerna och överför kontrollen till den riktade iterationen eller switch-instruktionsetiketten.

En märkt continue behöver inte matchas i något lokalt omfång. Sökningen efter en matchande etikett kan continue upp anropsstacken även över skript- och funktionsanropsgränser. Om ingen matchande etikett hittas avslutas det aktuella kommandoanropet.

Namnet på etiketten som anges av etikettuttryck behöver inte ha ett konstant värde.

Om etikettuttryck är ett unary-uttryckkonverteras det till en sträng.

Exempel:

$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 Kastsatsen

Beskrivning:

Ett undantag är ett sätt att hantera ett feltillstånd på system- eller programnivå. Throw-satsen utlöser ett undantag. (Se §8.7 för en diskussion om undantagshantering.)

Om pipeline utelämnas och utkastssatsen inte finns i en fångst-klausul, är beteendet implementationsdefinierat. Om pipeline finns och throw-satsen är i en catch-klausul, kastas undantaget som fångades av den catch-klausul igen efter att någon finally-sats som är associerad med catch-klausul har körts.

Om pipeline finns, är typen av undantaget som genereras implementationsdefinierad.

När ett undantag utlöses överförs kontrollen till den första catch-satsen i en omslutande try-instruktion som kan hantera undantaget. Platsen där undantaget utlöses från början kallas startpunkt. När ett undantag utlöses följs de steg som beskrivs i §8.7 upprepade gånger tills en fångstklausul som matchar undantaget hittas eller ingen kan hittas.

Exempel:

throw
throw 100
throw "No such record in file"

Om pipeline utelämnas och instruktionen throw inte kommer från en catch-clauseskrivs texten "ScriptHalted" till pipelinen och typen av undantag som genereras är System.Management.Automation.RuntimeException.

Om pipeline är närvarande, omsluts det undantag som uppstår i ett objekt av typen System.Management.Automation.RuntimeException, vilket inkluderar information om undantaget som ett System.Management.Automation.ErrorRecord-objekt (tillgängligt via $_).

Exempel 1: throw 123 resulterar i ett undantag av typen RuntimeException. Inifrån fångstblocket innehåller $_.TargetObject objektet som är inneslutet, i det här fallet en System.Int32 med värdet 123.

Exempel 2: throw "xxx" resulterar i ett undantag av typen RuntimeException. Från catch-blocket innehåller $_.TargetObject objektet som omsluts inuti, i det här fallet en System.String med värdet "xxx".

Exempel 3: throw 10,20 resulterar i ett undantag av typen RuntimeException. I catch-blocket innehåller $_.TargetObject objektet som omsluts, i det här fallet en System.Object[], en flexibel matris som har två element och innehåller System.Int32-värdena 10 och 20.

8.5.4 Retursatsen

Beskrivning:

return-instruktionen skriver till pipelinen de värden som anges av pipeline, om någon, och returnerar kontrollen till funktionen eller skriptets anropare. En funktion eller ett skript kan ha noll eller fler return-instruktioner.

Om körningen når den avslutande klammerparentesen för en funktion antas en underförstådd return utan pipeline.

Den return instruktionen är lite av "syntaktisk socker" för att göra det möjligt för programmerare att uttrycka sig som de kan på andra språk; Värdet som returneras från en funktion eller ett skript är dock faktiskt alla värden som skrivs till pipelinen av den funktionen eller skriptet plus alla värden som anges av pipeline. Om endast ett skalärt värde skrivs till pipelinen är dess typ den typ av värde som returneras. Annars är returtypen en obegränsad 1-dimensionell matris som innehåller alla värden som skrivits till pipelinen.

Exempel:

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

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

Anroparen till Get-Factorial får tillbaka en 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
}

Anroparen till Test får tillbaka en obegränsad 1-dimensionell matris med tre element.

8.5.5 Slutsatsen

Beskrivning:

Exit-instruktionen avslutar det aktuella skriptet och returnerar kontrollen och en slutkod till värdmiljön eller det anropande skriptet. Om rörledning tillhandahålls, konverteras det värde som den anger till int, om det behövs. Om det inte finns någon sådan konvertering, eller om pipeline utelämnas, returneras int-värdet noll.

Exempel:

exit $count # terminate the script with some accumulated count

8.6 Switch-instruktionen

Syntax:

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

Beskrivning:

Om switch-condition anger ett enda värde skickas kontrollen till ett eller flera matchande mönsteruttrycksblock. Om inga mönster matchar kan någon standardåtgärd vidtas.

En växel måste innehålla en eller flera switch-clauses, var och en börjar med ett mönster (en icke-standardväxelsats), eller nyckelordet default (en standardväxelsats). En switch måste innehålla noll eller en default switch-sats och noll eller fler icke-standardmässiga switch-satser. Switch-satser kan skrivas i valfri ordning.

Flera mönster kan ha samma värde. Ett mönster behöver inte vara en literal, och en växel kan ha mönster med olika typer.

Om värdet för switch-condition matchar ett mönstervärde körs det mönstrets instruktionsblock. Om flera mönstervärden matchar värdet för switch-condition, utförs varje matchande mönsters statement-block i lexikal ordning, såvida inte något av dessa statement-blockinnehåller en break-instruktion (§8.5.1).

Om värdet för växel-villkor inte matchar något mönstervärde och det finns en default växel-sats, så körs dess instruktionblock. Annars avslutas mönstermatchningen för det växel-villkor.

Växlar kan kapslas, där varje växel har en egen uppsättning switch-satser. I sådana fall tillhör en switch-sats den innersta växeln som för närvarande finns i omfånget.

Vid inmatning till varje kodblocktilldelas $_ automatiskt värdet av den switch-villkor som gjorde att kontrollen flyttades till det kodblocket. $_ finns också i det -instruktionsblocketswitch-clause-condition.

Matchning av icke-strängvärden görs genom att testa för jämlikhet (§7.8.1).

Om matchningen omfattar strängar är jämförelsen som standard skiftlägesokänslig. Närvaron av switch-parameter-CaseSensitive gör jämförelsen skiftlägeskänslig.

Ett mönster kan innehålla jokertecken (§3.15), i vilket fall jokerteckensträngsjämförelser utförs, men endast om switch-parameter-Wildcard finns. Som standard är jämförelsen inte skiftlägeskänslig.

Ett mönster kan innehålla ett reguljärt uttryck (§3.16), i vilket fall jämförelse av reguljära uttryckssträngar utförs, men endast om switch-parametern-Regex finns. Som standard är jämförelsen inte skiftlägeskänslig. Om -Regex finns och ett mönster matchas definieras $Matches i switch-clausestatement-block för det mönstret.

En switch-parameter kan förkortas; en distinkt inledande del av parametern kan användas. Till exempel är ‑Regex, ‑Rege, ‑Reg, ‑Reoch ‑R likvärdiga.

Om motstridiga switch-parameters anges, råder den lexikala slutparametern. Förekomsten av ‑Exact inaktiverar -Regex och -Wildcard; det har dock ingen inverkan på ‑Case.

Om switch-parametern‑Parallel anges, är beteendet definierat av implementeringen.

switch-parametern‑Parallel tillåts endast i ett arbetsflöde (§8.10.2).

Om ett mönster är ett script-block-expressionutvärderas blocket och resultatet konverteras till bool om det behövs. Om resultatet har värdet $true, körs motsvarande -instruktionsblock; annars körs det inte.

Om switch-condition anger flera värden tillämpas växeln på varje värde i lexikal ordning med hjälp av reglerna som beskrivs ovan för en switch-condition som anger ett enda värde. Varje switch-instruktion har en egen uppräknare, $switch (§2.3.2.2, §4.5.16), som endast finns medan växeln körs.

En switch-instruktion kan ha en etikett och kan innehålla etiketterade och oetiketterade bryt-satser (§8.5.1) och fortsätt-satser (§8.5.2).

Om switch-condition är -Fileswitch-filename, i stället för att iterera över värdena i ett uttryck, itererar växlingen över värdena i filen som anges av switch-filename. Filen läss en rad i taget med varje rad som består av ett värde. Radavgränsningstecken ingår inte i värdena.

Exempel:

$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 Instruktionen try/finally-satsen

Syntax:

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

Beskrivning:

Try-instruktionen innehåller en mekanism för att fånga undantag som inträffar under körningen av ett block. Try-instruktionen ger också möjlighet att ange ett kodblock som alltid körs när kontrollen lämnar try-instruktionen. Processen för att upphöja ett undantag via throw-satsen beskrivs i §8.5.3.

Ett försöksblock är det block av instruktioner som är associerat med try-instruktionen. Ett catch-block är associerad med en catch-clause. Ett slutligen blockera är associerad med en .

En catch-sats utan catch-typ-lista kallas för en allmän catch-sats.

Varje fångstsats är en undantagshanterare, och en fångstsats vars fångsttyplista innehåller typen av det uppkomna undantaget är en matchande fångstsats. En allmän catch-klausul matchar alla typer av undantag.

Även om catch-clauses och är valfria, måste minst en av dem finnas.

Bearbetningen av ett undantag som genereras består av att utvärdera följande steg upprepade gånger tills en catch-sats som matchar undantaget hittas.

  • Inom den nuvarande omfattningen granskas varje try-sats som omger kastpunkten. Följande steg utvärderas för varje try-instruktion S, som börjar med den innersta try-instruktionen och slutar med den yttersta try-instruktionen:

    • Om try blocket i S omsluter kastpunkten och om S har en eller flera fångstklausuler, undersöks fångstklausulerna i lexikal ordning för att hitta en lämplig hanterare för undantaget. Den första catch-satsen som anger undantagstypen eller en bastyp av undantagstypen betraktas som en matchning. En allmän catch-sats anses vara en matchning för alla undantagstyper. Om en matchande catch-sats finns slutförs undantagsbearbetningen genom att kontrollen överförs till blocket i catch-satsen. I en matchande catch-sats innehåller variabeln $_ en beskrivning av det aktuella undantaget.

    • Annars, om try block eller ett catch block av S omsluter kastpunkten och om S har ett finally block, överförs kontrollen till det sista blocket. Om blocket finally utlöser ett annat undantag avslutas bearbetningen av det aktuella undantaget. Annars fortsätter bearbetningen av det aktuella undantaget när kontrollen når slutet av det finally blocket.

  • Om en undantagshanterare inte finns i det aktuella omfånget upprepas stegen ovan för omfånget omslutande med en utlöspunkt som motsvarar instruktionen som det aktuella omfånget anropades från.

  • Om undantagsbearbetningen avslutas och alla scope upphör, vilket betyder att det inte finns någon hanterare för undantaget, är beteendet ospecificerat.

För att förhindra icke åtkomliga catch-satser i ett försöksblock kan det hända att en catch-sats inte anger en undantagstyp som är lika med eller härledd från en typ som angavs i en tidigare catch-sats inom samma försöksblock.

Instruktioner för ett finally block körs alltid när kontrollen lämnar en try -instruktion. Detta gäller om kontrollöverföringen sker som ett resultat av normal körning, som ett resultat av att en break, continueeller return-instruktionen körs, eller som ett resultat av ett undantag som utlöses från try-instruktionen.

Om ett undantag utlöses under körningen av ett finally-block kastas undantaget till nästa överordnade try-instruktion. Om ett annat undantag höll på att hanteras går undantaget förlorat. Processen för att generera ett undantag beskrivs ytterligare i beskrivningen av throw-instruktionen.

try-instruktioner kan samexistera med trap-instruktioner. se §8.8 för mer information.

Exempel:

$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 {
        # ...
    }
}

Varje undantag som kastas genereras som en System.Management.Automation.RuntimeException. Om det finns typspecifika catch-clause-s i try-blocket kontrolleras egenskapen InnerException för undantaget för att försöka hitta en matchning, till exempel med typen System.IndexOutOfRangeException ovan.

8.8 Trap-instruktionen

Syntax:

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

Beskrivning:

En trap-instruktion med och utan -typliteral är analog med ett catch-block (§8.7) med och utan -catch-type-list, förutom att en trap-instruktion bara kan fånga en typ i taget.

Flera trap-instruktioner kan definieras i samma instruktionsblockoch deras definitionsordning är irrelevant. Om två trap-instruktioner med samma typ-literal definieras i samma omfång används det lexikalt första för att hantera undantag av samma typ.

Till skillnad från ett catch block matchar en trap-instruktion exakt en undantagstyp. ingen matchning av härledd typ utförs.

Om det inte finns någon matchande trap-instruktion i det aktuella omfånget, söks en matchande trap-instruktion i det omslutande omfånget, vilket kan innebära att söka i det anropande skriptet, funktionen eller filtret och därefter i dennes anropare och så vidare. Om sökningen avslutas med alla omfång, vilket indikerar att det inte finns någon hanterare för undantaget, är beteendet ospecificerat.

En trap-instruktions instruktionstext körs endast för att bearbeta motsvarande undantag; annars passerar exekveringen över den.

Om en trapinstruktionskropp avslutas normalt, skrivs ett felobjekt som standard till felströmmen, undantaget betraktas som hanterat och körningen fortsätter med instruktionen omedelbart efter den inom det omfång som innehåller trap-instruktionen som gjorde undantaget synligt. Orsaken till undantaget kan finnas i ett kommando som anropas av kommandot som innehåller trap-instruktionen.

Om den slutgiltiga instruktionen som körs i en trapinstruktionstext är 'continue' (§8.5.2), undertrycks skrivningen av felobjektet till felströmmen, och körningen fortsätter med instruktionen direkt efter den i det omfång som innehåller den fälla-instruktion som gjorde undantaget synligt. Om den sista instruktionen som utförs i ett trap:s statement-body är break (§8.5.1), undertrycks skrivningen av felobjektet till felströmmen och undantaget kastas igen.

I en trap-instruktion innehåller variabeln $_ en beskrivning av det aktuella felet.

Tänk på det fall då ett undantag som genereras inifrån ett try block inte har ett matchande catch block, men det finns en matchande trap-instruktion på en högre blocknivå. När try-blockets slutsats har körts får trap-instruktionen kontroll även om något överordnat omfång har ett matchande catch block. Om en trap-instruktion definieras i själva try-blocket och det try blocket har ett matchande catch block, får trap-instruktionen kontroll.

Exempel:

I följande exempel skrivs felobjektet och körningen fortsätter med instruktionen omedelbart efter den som orsakade avbrottet; det vill säga, "Klar" skrivs till pipelinen.

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

I följande exempel ignoreras skrivningen av felobjektet och körningen fortsätter med instruktionen omedelbart efter den som orsakade fällan; det vill säga "Färdig" skrivs till pipelinen.

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

I följande exempel undertrycks skrivningen av felobjektet och undantaget kastas om.

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

I följande exempel finns trap- och undantagsgenererande instruktioner i samma omfång. När undantaget har fångats upp och hanterats, återupptas körningen med att skriva 1 till rörledningen.

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

I följande exempel finns trap- och undantagsgenererande instruktioner i olika omfattningar. När undantaget har fångats och hanterats återupptas körningen med att skriva 2 (inte 1) till pipelinen.

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

8.9 Data-instruktionen

Syntax:

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

Beskrivning:

Ett datauttryck skapar ett dataavsnittoch håller avsnittets data åtskilda från koden. Den här separationen stöder funktioner som separata strängresursfiler för text, till exempel felmeddelanden och hjälpsträngar. Det hjälper också till att stödja internationalisering genom att göra det enklare att isolera, hitta och bearbeta strängar som kommer att översättas till olika språk.

Ett skript eller en funktion kan ha noll eller flera dataavsnitt.

uttalande-block i ett dataavsnitt är begränsat till att endast innehålla följande PowerShell-funktioner:

  • Alla operatorer utom -match
  • Påståendet if
  • Följande automatiska variabler: $PSCulture, $PSUICulture, $true, $falseoch $null.
  • Kommentarer
  • Rörledningar
  • Utsagor avgränsade med semikolon (;)
  • Literaler
  • Anrop till cmdleten ConvertFrom-StringData
  • Andra cmdletar som identifieras via parametern SupportedCommand

Om cmdleten ConvertFrom-StringData används kan nyckel/värde-par uttryckas med valfri form av strängliteral. Emellertid får expandable-string-literals och expandable-here-string-literals inte innehålla några variabelersättningar eller underuttrycksexpansioner.

Exempel:

Parametern SupportedCommand anger att de angivna cmdletarna eller funktionerna endast genererar data. Följande dataavsnitt innehåller till exempel en användarskriven cmdlet, ConvertTo-Xml, som formaterar data i en XML-fil:

data -SupportedCommand ConvertTo-Xml {
    Format-Xml -Strings string1, string2, string3
}

Tänk på följande exempel, där dataavsnittet innehåller ett ConvertFrom-StringData kommando som konverterar strängarna till en hash-tabell, vars värde har tilldelats till $messages.

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

Nycklarna och värdena i hash-tabellen nås med hjälp av $messages.Greeting, $messages.Yesrespektive $messages.No.

Nu kan detta sparas som en engelskspråkig resurs. Tyska och spanska resurser kan skapas i separata filer med följande dataavsnitt:

$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
"@
}

Om datanamn finns namnger den variabeln (utan att använda en inledande $) som värdet för datautsatsen ska lagras i. Mer specifikt motsvarar $name = data { ... }data name { ... }.

8.10 Funktionsdefinitioner

Syntax:

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

Beskrivning:

En funktionsdefinition anger namnet på funktionen, filtret eller arbetsflödet som definieras och namnen på dess parametrar, om några. Den innehåller även noll eller fler instruktioner som körs för att uppnå funktionens syfte.

Varje funktion är en instans av klassen System.Management.Automation.FunctionInfo.

8.10.1 Filterfunktioner

Medan en vanlig funktion körs en gång i en pipeline och kommer åt indatasamlingen via $inputär ett filter en speciell typ av funktion som körs en gång för varje objekt i indatasamlingen. Objektet som bearbetas är tillgängligt via variabeln $_.

Ett filter utan namngivna block (§8.10.7) motsvarar en funktion med ett processblock, men utan startblock eller slutblock.

Överväg följande filterfunktionsdefinition och -anrop:

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

Varje filter är en instans av klassen System.Management.Automation.FilterInfo (§4.5.11).

8.10.2 Arbetsflödesfunktioner

En arbetsflödesfunktion är som en vanlig funktion med implementeringsdefinierad semantik. En arbetsflödesfunktion översätts till en sekvens med Windows Workflow Foundation-aktiviteter och körs i Windows Workflow Foundation-motorn.

8.10.3 Argumenthantering

Överväg följande definition för en funktion som heter Get-Power:

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

Den här funktionen har två parametrar, $Base och $Exponent. Den innehåller också en uppsättning instruktioner som för icke-negativa exponentvärden beräknar $Base^$Exponent^ och returnerar resultatet till Get-Poweranropare.

När ett skript, en funktion eller ett filter börjar köras initieras varje parameter till motsvarande argumentvärde. Om det inte finns något motsvarande argument och ett standardvärde (§8.10.4) anges används det värdet. annars används värdet $null. Därför är varje parameter en ny variabel, som om den hade initierats genom tilldelning i början av skriptblock.

Om en skriptparameter innehåller en typbegränsning (till exempel [long] och [int] ovan) konverteras värdet för motsvarande argument till den typen om det behövs. annars sker ingen konvertering.

När ett skript, en funktion eller ett filter börjar köras definieras variabeln $args inuti den som en obehindrat 1-dimensionell matris, som innehåller alla argument som inte är bundna av namn eller position, i lexikal ordning.

Överväg följande funktionsdefinition och -anrop:

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

Mer information om parameterbindning finns i §8.14.

8.10.4 Parameterinitierare

Deklarationen av en parameter p kan innehålla en initialiserare, i vilket fall initierarens värde används för att initiera p förutsatt att p inte är bunden till några argument i anropet.

Överväg följande funktionsdefinition och -anrop:

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

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

8.10.5 [switch]-typvillkoret

När en [switch] parameter skickas måste motsvarande parameter i kommandot begränsas av typväxeln. Typväxeln har två värden, True och False.

Överväg följande funktionsdefinition och -anrop:

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 Pipelines och funktioner

När ett skript, en funktion eller ett filter används i en pipeline levereras en samling värden till skriptet eller funktionen. Skriptet, funktionen eller filtret får åtkomst till samlingen via uppräknaren $input (§2.3.2.2, §4.5.16), som definieras vid inmatning till skriptet, funktionen eller filtret.

Överväg följande funktionsdefinition och -anrop:

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 Namngivna block

Instruktionerna i ett skriptblock kan tillhöra ett stort namnlöst block, eller så kan de distribueras till ett eller flera namngivna block. Namngivna block tillåter anpassad bearbetning av samlingar som kommer från pipelines; namngivna block kan definieras i valfri ordning.

Instruktionerna i en begin-block (dvs. en som är markerad med nyckelordet begin) körs en gång, innan det första pipelineobjektet levereras.

Instruktionerna i ett processblock (dvs. ett som markerats med nyckelordsprocessen) körs för varje pipelineobjekt som levereras. ($_ ger åtkomst till det aktuella objektet som bearbetas från indatasamlingen som kommer från pipelinen.) Det innebär att om en samling med noll element skickas via pipelinen körs inte processblocket alls. Men om skriptet eller funktionen anropas utanför en pipelinekontext körs det här blocket exakt en gång och $_ är inställt på $nulleftersom det inte finns något aktuellt samlingsobjekt.

Uttalandena i ett slutblock (dvs. ett som är markerat med nyckelordet 'end') körs efter att det sista pipelineobjektet har levererats, en gång.

8.10.8 dynamicparam block

Hittills hanterar underavsnitten i §8.10statiska parametrar, som definieras som en del av källkoden. Det är också möjligt att definiera dynamiska parametrar via ett dynamicparam-block, en annan form av namngivet block (§8.10.7), som markeras med nyckelordet dynamicparam. Mycket av denna maskineri är implementeringsdefinierad.

Dynamiska parametrar är parametrar för en cmdlet, funktion, filter eller skript som endast är tillgängliga under vissa förhållanden. Ett sådant fall är parametern Kodning för cmdleten Set-Item.

I statement-blockanvänder du en if-instruktion för att ange de villkor under vilka parametern är tillgänglig i funktionen. Använd cmdleten New-Object för att skapa ett objekt av en implementeringsdefinierad typ för att representera parametern och ange dess namn. Använd också New-Object för att skapa ett objekt av en annan implementeringsdefinierad typ för att representera parameterns implementeringsdefinierade attribut.

I följande exempel visas en funktion med standardparametrar som kallas Namn och Sökväg och en valfri dynamisk parameter med namnet DP1. Parametern DP1 finns i parameteruppsättningen PSet1 och har en typ av Int32. Parametern DP1 är endast tillgänglig i exempelfunktionen när värdet för parametern Path innehåller "HKLM:", vilket anger att den används i HKEY_LOCAL_MACHINE registerenheten.

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

Den typ som används för att skapa ett objekt för att representera en dynamisk parameter är System.Management.Automation.RuntimeDefinedParameter.

Den typ som används för att skapa ett objekt för att representera parameterns attribut är System.Management.Automation.ParameterAttribute.

De implementeringsdefinierade attributen för parametern omfattar Obligatorisk, Positionoch ValueFromPipeline.

8.10.9 param block

Ett param-block- ger ett alternativt sätt att deklarera parametrar. Följande uppsättningar med parameterdeklarationer är till exempel likvärdiga:

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

En param-block tillåter en attributlistaparam-block medan en funktionsparameterdeklaration inte gör det.

Ett skript kan ha en param-block men inte en function-parameter-declaration. En funktions- eller filterdefinition kan ha en funktionsparameterdeklaration eller en parameterblock, men inte båda.

Tänk på följande exempel:

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

Den enda parametern, $ComputerName, har typen string[], den krävs och den tar indata från pipelinen.

Se §12.3.7 för en diskussion om attributet Parameter och för fler exempel.

8.11 Det parallella påståendet

Syntax:

parallel-statement:
    *parallel* statement-block

Den parallella instruktionen innehåller noll eller fler instruktioner som körs på ett implementeringsdefinierat sätt.

En parallell instruktion tillåts endast i ett arbetsflöde (§8.10.2).

8.12 Sekvenssatsen

Syntax:

sequence-statement:
    *sequence* statement-block

Sekvensinstruktionen innehåller noll eller fler instruktioner som körs på ett implementeringsdefinierat sätt.

En sekvenssats tillåts endast i ett arbetsflöde (§8.10.2).

8.13 Inlineskript-satsen

Syntax:

inlinescript-statement:
    inlinescript statement-block

Den infogade instruktionen innehåller noll eller fler instruktioner som exekveras på ett implementationsspecifikt sätt.

En inlinescript-instruktion tillåts endast i ett arbetsflöde (§8.10.2).

8.14 Parameterbindning

När ett skript, en funktion, ett filter eller en cmdlet anropas kan varje argument bindas till motsvarande parameter efter position, där den första parametern har position noll.

Överväg följande definitionsfragment för en funktion som heter Get-Poweroch anropen till den:

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

När ett skript, en funktion, ett filter eller en cmdlet anropas kan ett argument bindas till motsvarande parameter efter namn. Detta görs med hjälp av en parameter med argumentet, som är ett argument som är parameterns namn med ett inledande bindestreck (-), följt av det associerade värdet för argumentet. Parameternamnet som används kan ha valfri skiftlägesokänslig stavning och kan använda alla prefix som unikt anger motsvarande parameter. När du väljer parameternamn bör du undvika att använda namnen på de vanliga parametrarna.

Överväg följande anrop till funktionen 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

Å andra sidan anropas följande funktion

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

måste använda parametrar -Side1 och -Side2eftersom det inte finns något prefix som unikt anger parametern.

Samma parameternamn kan inte användas flera gånger med eller utan olika associerade argumentvärden.

Parametrar kan ha attribut (§12). Information om de enskilda attributen finns i avsnitten i §12.3. Information om parameteruppsättningar finns i §12.3.7.

Ett skript, en funktion, ett filter eller en cmdlet kan ta emot argument via kommandoraden för anrop, från pipelinen eller från båda. Här följer stegen i ordning för att lösa parameterbindningen:

  1. Bind alla namngivna parametrar, därefter
  2. Bind positionsparametrar och sedan
  3. Bind från pipelinen efter värde (§12.3.7) med exakt matchning, sedan
  4. Bind från pipelinen med ett värde (§12.3.7) och konvertera, sedan
  5. Bind från pipelinen efter namn (§12.3.7) med exakt matchning, sedan
  6. Bind från pipelinen efter namn (§12.3.7) med konvertering

Flera av dessa steg omfattar konvertering, enligt beskrivningen i §6. Den uppsättning konverteringar som används i bindning är dock inte exakt samma som den som används i språkkonverteringar. Specifikt

  • Även om värdet $null kan omvandlas till bool kan $null inte bindas till bool.
  • När värdet $null skickas till en [switch] parameter för en cmdlet behandlas det som om $true det skickades. Men när den skickas till en [switch] parameter för en funktion behandlas den som om $false den skickades.
  • Parametrar av typen bool eller switch kan bara binda till numeriska argument eller bool-argument.
  • Om parametertypen inte är en samling, men argumentet är någon typ av samling, görs inget konverteringsförsök om inte parametertypen är objekt eller PsObject. (Huvudpunkten i den här begränsningen är att inte tillåta konvertering av en samling till en strängparameter.) Annars görs de vanliga konverteringarna.

Om parametertypen är IList eller ICollection<T>görs endast dessa konverteringar via konstruktorn, op_Implicit och op_Explicit. Om det inte finns några sådana konverteringar används en särskild konvertering för parametrar av typen "samling" som innehåller IList, ICollection<T>och matriser.

Positionsparametrar föredrar att vara bundna utan typkonvertering, om möjligt. Ett exempel:

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"