8. Příkazy

8.1 Bloky a seznamy příkazů

Syntaxe:

Tip

Zápis ~opt~ v definicích syntaxe označuje, že lexikální entita je v syntaxi nepovinná.

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

Popis:

Příkaz určuje určitý druh akce, která se má provést. Pokud není v této klauzuli uvedeno jinak, příkazy se provádějí v lexikálním pořadí.

Blok příkazů umožňuje seskupit sadu příkazů do jedné syntaktické jednotky.

8.1.1 Příkazy s popisky

Syntaxe:

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

Popis:

Příkaz iterace (§8.4) nebo příkaz switch (§8.6) může být volitelně bezprostředně předcházet popiskem jednoho příkazu, popiskem. Popisek příkazu se používá jako volitelný cíl přerušení (§8.5.1) nebo pokračovat (§8.5.2). Popisek ale nezmění tok řízení.

Prázdné znaky nejsou povoleny mezi dvojtečku (:) a tokenem, který následuje za ním.

Příklady:

: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 Hodnoty příkazů

Hodnota příkazu je kumulativní sada hodnot, které zapisuje do kanálu. Pokud příkaz zapíše jednu skalární hodnotu, je to hodnota příkazu. Pokud příkaz zapíše více hodnot, hodnota příkazu je, že sada hodnot uložených v prvcích unconstrained 1-dimenzionální pole v pořadí, v jakém byly zapsány. Uvažujte následující příklad:

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

Smyčka neobsahuje žádné iterace a do kanálu se nic nezapisuje. Hodnota příkazu je $null.

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

I když smyčka iteruje pětkrát nic není zapsáno do kanálu. Hodnota příkazu je $null.

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

Smyčka iteruje pětkrát při každém zápisu int do kanálu hodnotu $i. Hodnota příkazu je object[] délka 5.

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

I když smyčka iteruje pětkrát nic není zapsáno do kanálu. Hodnota příkazu je $null.

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

Smyčka iteruje pětkrát s každou hodnotou, která se zapisuje do kanálu. Hodnota příkazu je object[] délka 5.

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

Smyčka se jednou iteruje. Hodnota příkazu je int s hodnotou 2.

Tady jsou některé další příklady:

# 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 Příkazy kanálu

Syntaxe:

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

Popis:

přesměrování je popsáno v §7.12; výraz přiřazení je popsán v §7.11; a tečka operátoru volání příkazu (.) je popsána v §3.5.5. Diskuzi o mapování argument-to-parameter při vyvolání příkazů naleznete v části §8.14.

Prvním příkazem v kanálu je výraz nebo vyvolání příkazu. Vyvolání příkazu obvykle začíná názvem příkazu, což je obvykle holý identifikátor. command-elements představuje seznam argumentů příkazu. Nový řádek nebo n neuskutečená středník ukončí kanál.

Vyvolání příkazu se skládá z názvu příkazu následovaného nulou nebo více argumenty. Pravidla, která řídí argumenty, jsou následující:

  • Argument, který není výrazem, ale který obsahuje libovolný text bez nepostřebné prázdné mezery, je považován za dvojitý uvozovek. Písmena se zachovají.

  • Proměnné nahrazení a rozšíření dílčího výrazu (§2.3.5.2) probíhá uvnitř expandable-string-literal s a expandable-here-string-literal s.

  • Text uvnitř uvozovek umožňuje zahrnout počáteční, koncové a vložené prázdné znaky do hodnoty argumentu. [Poznámka: Přítomnost prázdných znaků v uvozovaném argumentu nemění jeden argument na více argumentů. end note]

  • Umístění závorek kolem argumentu způsobí, že se výraz vyhodnotí s výsledkem předaným namísto textu původního výrazu.

  • Chcete-li předat argument, který vypadá jako parametr přepínače (§2.3.4), ale není zamýšlen jako takový, uzavřete tento argument do uvozovek.

  • Při zadávání argumentu, který odpovídá parametru [switch] s omezením typu (§8.10.5), přítomnost názvu argumentu na vlastní straně způsobí, že parametr bude nastaven na $true. Hodnotu parametru ale můžete explicitně nastavit tak, že k argumentu připojíte příponu. Například vzhledem k omezenému parametru typu p argument -p:$true množiny p na Hodnotu True, zatímco -p:$false hodnota p je false.

  • Argument -- označuje, že všechny argumenty, které následují, mají být předány ve skutečné podobě, jako by se kolem nich umístily dvojité uvozovky.

  • Argument --% označuje, že všechny argumenty, které následují, se předávají s minimální analýzou a zpracováním. Tento argument se nazývá doslovný parametr. Argumenty za doslovnými parametry nejsou výrazy PowerShellu, i když jsou syntakticky platné výrazy PowerShellu.

Pokud je typem příkazu Aplikace, parametr --% se do příkazu nepředá. Argumenty po --% rozbalení všech proměnných prostředí (řetězce obklopené %) Příklad:

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

Pořadí vyhodnocení argumentů není zadané.

Informace o vazbě parametrů naleznete v části §8.14. Informace o vyhledávání názvů naleznete v části §3.8.

Po dokončení zpracování argumentů se vyvolá příkaz. Pokud se vyvoláný příkaz normálně ukončí (§8.5.4), ovládací prvek se vrátí k bodu ve skriptu nebo funkci bezprostředně po vyvolání příkazu. Popis chování při neobvyklém ukončení viz break(§8.5.1), continue (§8.5.2), throw (§8.5.3), exit (§8.5.5), try (§8.7) a trap(§8.8.8).

Obvykle se příkaz vyvolá pomocí názvu následovaného libovolnými argumenty. Lze však použít operátor volání příkazů, &. Pokud název příkazu obsahuje nepotřebné prázdné znaky, musí být citováno a vyvoláno pomocí tohoto operátoru. Protože blok skriptu nemá žádný název, musí být také vyvolán s tímto operátorem. Například následující vyvolání volání příkazu Get-Factorial jsou ekvivalentní:

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

Volání přímých a nepřímých rekurzivních funkcí jsou povolená. Třeba

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

Příklady:

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 Příkaz if

Syntaxe:

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

Popis:

Řídicí výrazy kanálu musí mít logickou hodnotu typu nebo musí být implicitně konvertovat na tento typ. Klauzule else je volitelná. Může existovat nula nebo více klauzulí elseif-s.

Pokud kanál nejvyšší úrovně testuje hodnotu True, jeho blok příkazů se spustí a spuštění příkazu se ukončí. Jinak platí, že pokud je k dispozici klauzule elseif-clause , pokud je její test kanálu True, jeho blok příkazů se spustí a spuštění příkazu se ukončí. Jinak platí, že pokud je k dispozici klauzule else , spustí se jeho blok příkazů .

Příklady:

$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 Příkazy iterace

8.4.1 Příkaz while

Syntaxe:

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

while-condition:
    new-lines~opt~ pipeline

Popis:

Řídicí výraz while-condition musí mít typ bool nebo musí být implicitně převést na tento typ. Tělo smyčky, která se skládá z bloku příkazů, se provádí opakovaně, dokud řídicí výraz nepravda testuje. Řídicí výraz se vyhodnotí před každým spuštěním těla smyčky.

Příklady:

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

8.4.2 Příkaz do

Syntaxe:

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

Popis:

Řídicí výraz while-condition musí mít typ bool nebo musí být implicitně převést na tento typ. Ve formuláři se tělo smyčky, která se skládá z bloku příkazů, se provádí opakovaně, zatímco řídicí výraz testuje hodnotu True. V podobě dokud se tělo smyčky nespustí opakovaně, dokud řídicí výraz neprotestuje hodnotu True. Řídicí výraz se vyhodnotí po každém spuštění těla smyčky.

Příklady:

$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 Příkaz for

Syntaxe:

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

Popis:

Řídicí výraz pro podmínku musí mít typ bool nebo musí být implicitně převoditelný na tento typ. Tělo smyčky, která se skládá z bloku příkazů, se provádí opakovaně, zatímco řídicí výraz testuje hodnotu True. Řídicí výraz se vyhodnotí před každým spuštěním těla smyčky.

Výraz pro inicializátor se vyhodnotí před prvním vyhodnocením řídicího výrazu. Výraz pro inicializátor je vyhodnocen pouze pro jeho vedlejší účinky; jakákoli hodnota, kterou vytvoří, se zahodí a nezapíše se do kanálu.

Výraz pro iterátor se vyhodnotí po každém spuštění těla smyčky. Výraz pro iterátor je vyhodnocen pouze pro jeho vedlejší účinky; jakákoli hodnota, kterou vytvoří, se zahodí a nezapíše se do kanálu.

Pokud je výraz pro podmínku vynechán, řídicí výraz testuje hodnotu True.

Příklady:

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 Příkaz foreach

Syntaxe:

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

Popis:

Tělo smyčky, která se skládá z bloku příkazů, se provádí pro každý prvek určený proměnnou proměnné v kolekci určené kanálem. Rozsah proměnné není omezen na příkaz foreach. Proto si zachová konečnou hodnotu po dokončení provádění textu smyčky. Pokud kanál místo kolekce určí skalární (s výjimkou hodnoty $null), bude se tento skalár považovat za kolekci jednoho prvku. Pokud kanál určí hodnotu $null, kanál se považuje za kolekci nulových prvků.

Pokud je zadán parametr -parallel foreach, chování je definováno implementací.

Parametr ‑parallel foreach je povolen pouze v pracovním postupu (§8.10.2).

Každý příkaz foreach má vlastní výčet $foreach (§2.3.2.2, §4.5.16), který existuje pouze při provádění této smyčky.

Objekty vytvořené kanálem se shromažďují před zahájením spuštění bloku příkazů . Při použití rutiny ForEach-Object se však příkazový blok spustí na každém objektu, jak se vytváří.

Příklady:

$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 ovládacích příkazů

Syntaxe:

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

Popis:

Příkaz řízení toku způsobí nepodmíněný přenos řízení do jiného umístění.

8.5.1 Příkaz break

Popis:

Příkaz break s výrazem popisku se označuje jako příkaz break s popiskem. Příkaz break bez výrazu popisku se označuje jako neoznačené příkaz break.

Mimo příkaz trap ukončí příkaz bez znaménku přerušení přímo v příkazu iterace (§8.4) provádění tohoto nejmenšího příkazu iterace. Příkaz bez znaména přerušení přímo v příkazu switch (§8.6) ukončí vzor odpovídající stavu přepínače aktuálního přepínače. Podrobnosti o použití přestávky v rámci příkazu pasti najdete v článku (§8.8).

Příkaz iterace nebo příkaz switch může volitelně předcházet okamžitě jedním popiskem příkazu (§8.1.1). Takový popisek příkazu lze použít jako cíl příkazu break s popiskem, v takovém případě tento příkaz ukončí provádění cílového příkazu iterace.

V žádném místním oboru není potřeba vyřešit označený konec; hledání odpovídajícího popisku může pokračovat v zásobníku volání i napříč hranicemi skriptů a volání funkcí. Pokud se nenajde žádný odpovídající popisek, vyvolání aktuálního příkazu se ukončí.

Název popisku určeného výrazem popisku nemusí mít konstantní hodnotu.

Pokud je výraz popisku unární výraz, převede se na řetězec.

Příklady:

$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 Příkaz continue

Popis:

Příkaz continue s výrazem label se označuje jako příkaz continue s popiskem. Příkaz continue bez výrazu label se označuje jako neoznačené příkaz continue.

Použití continue příkazu z pasti je popsáno v §8.8.

Nezaznamenaný continue příkaz v rámci smyčky ukončí provádění aktuální smyčky a převede kontrolu na pravou závorku nejmenšího uzavřeného příkazu iterace (§8.4). Neoznačený continue příkaz v rámci přepínače ukončí provádění aktuální switch iterace a převede řízení na nejmenší uzavřenou switchpodmínku přepínače (§8.6).

Příkaz iterace nebo switch příkaz (§8.6) může být volitelně bezprostředně před jedním popiskem příkazu (§8.1.1). Takový popisek příkazu se může použít jako cíl uzavřeného popisovaného continue příkazu, v takovém případě tento příkaz ukončí provádění aktuální smyčky nebo switch iterace a přenese ovládací prvek do cílového iterace nebo switch popisku příkazu.

Popisek continue nemusí být vyřešen v žádném místním oboru. Hledání odpovídajícího popisku může continue obsahovat zásobník volání i přes hranice skriptu a volání funkcí. Pokud se nenajde žádný odpovídající popisek, vyvolání aktuálního příkazu se ukončí.

Název popisku určeného výrazem popisku nemusí mít konstantní hodnotu.

Pokud je výraz popisku unární výraz, převede se na řetězec.

Příklady:

$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 Příkaz throw

Popis:

Výjimkou je způsob zpracování stavu chyby na úrovni systému nebo aplikace. Příkaz throw vyvolá výjimku. (Viz §8.7 pro diskuzi o zpracování výjimek.)

Pokud je kanál vynechán a příkaz throw není v klauzuli catch-clause, chování je definováno. Pokud je kanál k dispozici a příkaz throw je v klauzuli catch, výjimka zachycená touto klauzulí catch-clause je znovu vyvolána po provedení jakékoli klauzule finally-clause přidružené k klauzuli catch-clause .

Pokud je kanál k dispozici, typ vyvoláné výjimky je definován implementací.

Když je vyvolána výjimka, ovládací prvek se přenese do první catch klauzule v uzavřeném příkazu try, který může zpracovat výjimku. Umístění, na kterém je vyvolána výjimka původně, se nazývá bod vyvolání. Po vyvolání výjimky se kroky popsané v §8.7 opakují, dokud nenajdete klauzuli catch, která odpovídá výjimce, nebo se nenajde žádná.

Příklady:

throw
throw 100
throw "No such record in file"

Pokud je kanál vynechán a příkaz throw není z klauzule catch-clause, text ScriptHalted se zapíše do kanálu a typ vyvolání výjimky je System.Management.Automation.RuntimeException.

Pokud je kanál , vyvolána výjimka je zabalena do objektu typu System.Management.Automation.RuntimeException, který obsahuje informace o výjimce jako System.Management.Automation.ErrorRecord objekt (přístupný prostřednictvím $_).

Příklad 1: throw 123 výsledkem je výjimka typu RuntimeException. V rámci bloku $_.TargetObject catch obsahuje objekt zabalený uvnitř, v tomto případě s System.Int32 hodnotou 123.

Příklad 2: throw "xxx" výsledkem je výjimka typu RuntimeException. V rámci bloku $_.TargetObject catch obsahuje objekt zabalený uvnitř, v tomto případě System.String s hodnotou xxx.

Příklad 3: throw 10,20 výsledkem je výjimka typu RuntimeException. V rámci bloku $_.TargetObject catch obsahuje objekt zabalený uvnitř, v tomto případě System.Object[], unconstrained array of two element with the System. Hodnoty int32 10 a 20.

8.5.4 Příkaz return

Popis:

Příkaz return zapíše do kanálu hodnoty určené kanálem, pokud existuje, a vrátí ovládací prvek volajícímu funkce nebo skriptu. Funkce nebo skript můžou mít nulové nebo více return příkazů.

Pokud provádění dosáhne konečné závorky funkce implicitně return bez kanálu , předpokládá se.

Příkaz return je trochu "syntaktický cukr", který programátorům umožní vyjádřit se tak, jak můžou v jiných jazycích. Hodnota vrácená z funkce nebo skriptu je ale ve skutečnosti všechny hodnoty zapsané do kanálu pomocí této funkce nebo skriptu plus jakékoli hodnoty určené kanálem. Pokud je do kanálu zapsána pouze skalární hodnota, jeho typ je typ vrácené hodnoty; v opačném případě je návratový typ unconstrained 1-dimenzionální pole obsahující všechny hodnoty zapsané do kanálu.

Příklady:

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

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

Volající, aby Get-Factorial se vrátil 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
}

Volající Test získá zpět unconstrained 1-dimenzionální pole tří prvků.

8.5.5 Příkaz exit

Popis:

Příkaz exit ukončí aktuální skript a vrátí ovládací prvek a ukončovací kód do hostitelského prostředí nebo volajícího skriptu. Pokud je kanál zadaný, hodnota, kterou určí, se v případě potřeby převede na int. Pokud takový převod neexistuje nebo pokud není kanál vynechán, vrátí se hodnota int nula.

Příklady:

exit $count # terminate the script with some accumulated count

8.6 Příkaz switch

Syntaxe:

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

Popis:

Pokud podmínka přepínače určuje jednu hodnotu, předá se ovládací prvek jednomu nebo několika odpovídajícím blokům vzorového příkazu. Pokud se žádné vzory neshodují, je možné provést nějakou výchozí akci.

Přepínač musí obsahovat jednu nebo více klauzulí switch-klauzule, přičemž každá začíná vzorem ( výchozí klauzulí switch) nebo klíčovým default slovem ( výchozí klauzule switch). Přepínač musí obsahovat nulu nebo jednu default klauzuli switch a nulovou nebo více ne výchozích klauzulí switch. Klauzule Switch mohou být zapsány v libovolném pořadí.

Více vzorů může mít stejnou hodnotu. Vzor nemusí být literál a přepínač může mít vzory s různými typy.

Pokud hodnota podmínky přepínače odpovídá hodnotě vzoru, spustí se blok příkazů daného vzoru. Pokud se více hodnot vzorů shoduje s hodnotou podmínky přepínače, provede se blok příkazů každého odpovídajícího vzoru v lexikálním pořadí, pokud některý z těchto bloků příkazů neobsahuje break příkaz (§8.5.1).

Pokud hodnota podmínky přepínače neodpovídá žádné hodnotě vzoru, pokud default existuje klauzule switch, spustí se jeho blok příkazu ; jinak se ukončí shoda vzoru pro tuto podmínku switch-condition .

Přepínače mohou být vnořené, přičemž každý přepínač má vlastní sadu klauzulí switch. V takových případech patří klauzule switch do nejvnitřnějšího přepínače aktuálně v oboru.

Při zadávání do každého bloku$_ příkazů se automaticky přiřadí hodnota podmínky přepínače, která způsobila přechod na tento blok příkazů. $_ je také k dispozici v této klauzuli switch-clause-condition bloku příkazu.

Porovnávání neřetězců se provádí testováním rovnosti (§7.8.1).

Pokud porovnávání zahrnuje řetězce, ve výchozím nastavení je porovnání nerozlišující malá a velká písmena. Přítomnost parametru switch-parametr -casesensitive rozlišuje malá a velká písmena porovnání.

Vzor může obsahovat zástupné znaky (§3.15), v takovém případě se provádí porovnání řetězců se zástupnými znaky, ale pouze pokud je parametr přepínače -zástupný znak. Ve výchozím nastavení je porovnání nerozlišující malá a velká písmena.

Vzor může obsahovat regulární výraz (§3.16), v takovém případě se provádí porovnání řetězců regulárních výrazů, ale pouze v případě, že je parametr přepínače -regex k dispozici. Ve výchozím nastavení je porovnání nerozlišující malá a velká písmena. Pokud -regex je k dispozici a vzor je spárován, $matches je definován v bloku příkazů switch-klauzule pro tento vzor.

Parametr přepínače může být zkrácen; lze použít libovolnou jedinečnou úvodní část parametru. Například , ‑regex``‑re``‑rege``‑rega ‑r jsou ekvivalentní.

Pokud jsou zadány konfliktní parametry přepínače, lexicky konečný převládá. Přítomnost zakázání ‑exact -regex a -wildcard; nemá žádný vliv na ‑case, ale.

Pokud je zadaný parametr ‑parallel přepínače, chování je definováno implementací.

Parametr ‑parallel přepínače je povolen pouze v pracovním postupu (§8.10.2).

Pokud je vzor výrazem script-block-expression, vyhodnotí se tento blok a výsledek se v případě potřeby převede na bool. Pokud má výsledek hodnotu $true, provede se odpovídající blok příkazů , jinak to není.

Pokud podmínka přepínače určuje více hodnot, použije se přepínač na každou hodnotu v lexikálním pořadí pomocí pravidel popsaných výše pro podmínku přepínače , která určuje jednu hodnotu. Každý příkaz přepínače má svůj vlastní výčet $switch (§2.3.2.2, §4.5.16), který existuje pouze při provádění daného přepínače.

Příkaz switch může obsahovat popisek a může obsahovat popisek a neoznačené přerušení (§8.5.1) a pokračovat (§8.5.2).

Pokud je -file switch-condition switch-název souboru, místo iterace hodnot ve výrazu, přepínač iteruje hodnoty v souboru určeném přepínačem . Soubor načte řádek najednou s každým řádkem, který obsahuje hodnotu. Znaky ukončovací čáry nejsou zahrnuty do hodnot.

Příklady:

$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 Příkaz try/finally

Syntaxe:

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

Popis:

Příkaz try poskytuje mechanismus pro zachycení výjimek, ke kterým dochází během provádění bloku. Příkaz try také poskytuje možnost zadat blok kódu, který se vždy spustí, když ovládací prvek opustí příkaz try. Proces vyvolání výjimky prostřednictvím příkazu throw je popsán v §8.5.3.

Blok try je blok příkazu přidružený k příkazu try. A catch block is the statement-block associated with a catch-clause. A finally block is the statement-block associated with a finally-clause.

Klauzule catch bez seznamu catch-type-list se nazývá obecná catch klauzule.

Každá klauzule catch-clause je obslužná rutina výjimky a klauzule catch-clause , jejíž seznam catch-type-list obsahuje typ vyvolané výjimky, je odpovídající catch klauzule. Obecná klauzule catch odpovídá všem typům výjimek.

I když jsou klauzule catch a nakonec klauzule volitelné, musí existovat alespoň jedna z nich.

Zpracování vyvoláné výjimky se skládá z opakovaného vyhodnocení následujících kroků, dokud se nenajde klauzule catch, která odpovídá výjimce.

  • V aktuálním oboru se prověří každý příkaz try, který uzavře bod vyvolání. Pro každý příkaz try S, počínaje příkazem innermost try a končící na vnější příkaz try, jsou vyhodnoceny následující kroky:

    • try Pokud blok S uzavře bod vyvolání a pokud S obsahuje jednu nebo více zachytávání, jsou klauzule catch prozkoumány v lexikálním pořadí k vyhledání vhodné obslužné rutiny pro výjimku. První zachytácí klauzule, která určuje typ výjimky nebo základní typ typu výjimky, se považuje za shodu. Obecná klauzule catch se považuje za shodu pro jakýkoli typ výjimky. Pokud se nachází odpovídající klauzule catch, zpracování výjimek se dokončí převodem ovládacího prvku na blok této klauzule catch. V rámci odpovídající klauzule catch obsahuje proměnná $_ popis aktuální výjimky.

    • Jinak platí, že pokud try blok nebo catch blok S uzavře bod vyvolání a pokud S obsahuje finally blok, ovládací prvek se přenese do konečného bloku. finally Pokud blok vyvolá další výjimku, zpracování aktuální výjimky se ukončí. V opačném případě, když ovládací prvek dosáhne konce finally bloku, zpracování aktuální výjimky bude pokračovat.

  • Pokud obslužná rutina výjimky nebyla umístěna v aktuálním oboru, výše uvedené kroky se opakují pro uzavřený obor s bodem vyvolání odpovídající příkazu, ze kterého byl vyvolán aktuální obor.

  • Pokud zpracování výjimek ukončí všechny obory, což znamená, že pro výjimku neexistuje žádná obslužná rutina, není zadané chování.

Pokud chcete zabránit nedostupným klauzulím catch v bloku try, nesmí klauzule catch zadat typ výjimky, který je roven nebo odvozen z typu zadaného v dřívější klauzuli catch v rámci stejného bloku try.

Příkazy finally bloku se vždy spustí, když ovládací prvek opustí try příkaz. To platí, zda se přenos ovládacího prvku vyskytuje jako výsledek normálního spuštění, jako výsledek provádění breakpříkazu , continuenebo příkazu nebo return v důsledku vyvolání výjimky z try příkazu.

Pokud se během provádění finally bloku vyvolá výjimka, vyvolá se výjimka do dalšího try uzavřeného příkazu. Pokud při zpracování došlo k jiné výjimce, dojde ke ztrátě této výjimky. Proces generování výjimky je dále popsán v popisu throw příkazu.

try příkazy mohou existovat spolu s trap příkazy; viz §8.8 podrobnosti.

Příklady:

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

Každá vyvolána výjimka je vyvolána jako System.Management.Automation.RuntimeException. Pokud je v try bloku klauzule catch-specific pro typ, je vlastnost InnerException výjimky zkontrolována, aby se pokusila najít shodu, například s typem System.IndexOutOfRangeException výše.

8.8 Příkaz pasti

Syntaxe:

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

Popis:

Příkaz trap s a bez literálu typu je podobný catch bloku (§8.7) se seznamem typu catch a bez nich, s výjimkou toho, že trap příkaz může zachytávat pouze jeden typ najednou.

Více trap příkazů lze definovat ve stejném bloku příkazů a jejich pořadí definice je irelevantní. Pokud jsou ve stejném oboru definovány dva trap příkazy se stejným typem literálu , použije se lexicky první příkaz ke zpracování výjimky odpovídajícího typu.

catch Na rozdíl od bloku trap se příkaz přesně shoduje s typem výjimky. Neprovádí se žádná odvozená shoda typů.

Pokud dojde k výjimce, pokud v aktuálním oboru není k dispozici žádný odpovídající trap příkaz, vyhledá se odpovídající příkaz trapu v uzavřeném oboru, který může zahrnovat hledání ve volajícím skriptu, funkci nebo filtru, a pak v jeho volajícím atd. Pokud vyhledávání ukončí všechny obory, což znamená, že pro výjimku neexistuje žádná obslužná rutina, není zadané chování.

Text trap příkazu příkazu se provede pouze za účelem zpracování odpovídající výjimky, jinak ho provádění předá.

trapPokud se příkazový text obvykle ukončí, ve výchozím nastavení se do datového proudu chyby zapíše objekt chyby, považuje se za zpracovávanou výjimku a provádění pokračuje okamžitě za příkazem v oboru obsahujícím trap příkaz, který zviditelnil výjimku. Příčinou výjimky může být příkaz, který volá příkaz obsahující trap příkaz.

Pokud je konečný příkaz proveden v traptextu příkazu (§8.5.2), zápis objektu chyby do datového proudu chyby se potlačí a provádění pokračuje příkazem bezprostředně za příkazem v oboru obsahujícím příkaz trap, který zviditelnil výjimku. Pokud je konečný příkaz proveden v traptextu příkazu 's je konec (§8.5.1), zápis objektu chyby do datového proudu chyby je potlačován a výjimka je znovu vyvolána.

V příkazu proměnná trap $_ obsahuje popis aktuální chyby.

Vezměte v úvahu případ, kdy výjimka vyvolaná z try bloku nemá odpovídající blok, ale odpovídající catch trap příkaz existuje na vyšší úrovni bloku. try Jakmile se klauzule nakonec bloku spustí, příkaz získá kontrolu i v případě, trap že jakýkoli nadřazený obor má odpovídající catch blok. trap Pokud je příkaz definován v rámci samotného try bloku a tento try blok má odpovídající catch blok, trap příkaz získá kontrolu.

Příklady:

V následujícím příkladu se objekt chyby zapíše a spuštění pokračuje příkazem bezprostředně za příkazem, který způsobil past; to znamená, že "Hotovo" je zapsáno do kanálu.

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

V následujícím příkladu je zápis objektu chyby potlačován a provádění pokračuje příkazem bezprostředně za příkazem, který způsobil past; to znamená, že "Hotovo" je zapsáno do kanálu.

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

V následujícím příkladu se potlačí zápis objektu chyby a výjimka se znovu vyvolá.

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

V následujícím příkladu jsou příkazy pro generování výjimek ve stejném oboru. Po zachycení a zpracování výjimky se provádění obnoví zápisem 1 do kanálu.

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

V následujícím příkladu jsou příkazy generující výjimku v různých oborech. Po zachycení a zpracování výjimky se provádění obnoví zápisem 2 (ne 1) do kanálu.

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

8.9 Datový příkaz

Syntaxe:

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

Popis:

Datový příkaz vytvoří datový oddíl, přičemž data daného oddílu jsou oddělená od kódu. Toto oddělení podporuje zařízení, jako jsou samostatné soubory prostředků řetězců pro text, jako jsou chybové zprávy a řetězce nápovědy. Pomáhá také podporovat internationalizaci tím, že usnadňuje izolaci, vyhledání a zpracování řetězců, které budou přeloženy do různých jazyků.

Skript nebo funkce může mít nulové nebo více datových oddílů.

Blok příkazů datového oddílu je omezen pouze na následující funkce PowerShellu:

  • Všechny operátory kromě -match
  • Příkaz if
  • Následující automatické proměnné: $PsCulture, $PsUICulture, $true, $falsea $null.
  • Komentáře
  • Pipelines
  • Příkazy oddělené středníky (;)
  • Literály
  • Volání rutiny ConvertFrom-StringData
  • Všechny ostatní rutiny identifikované prostřednictvím podporovaného parametru

ConvertFrom-StringData Pokud se rutina používá, páry klíč/hodnota lze vyjádřit pomocí libovolného formátu řetězcového literálu. Expandable-string-literal s a expandable-here-string-literal s nesmí obsahovat žádné proměnné nahrazení ani rozšíření dílčích výrazů.

Příklady:

Parametr SupportedCommand označuje, že dané rutiny nebo funkce generují pouze data. Například následující část dat obsahuje rutinu napsanou uživatelem, ConvertTo-XMLkterá formátuje data v souboru XML:

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

Představte si následující příklad, ve kterém datový oddíl obsahuje ConvertFrom-StringData příkaz, který převede řetězce na tabulku hash, jejíž hodnota je přiřazena $messages.

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

K klíčům a hodnotám tabulky hash se přistupuje pomocí $messages.Greeting, $messages.Yesa $messages.No, v uvedeném pořadí.

Teď ho můžete uložit jako prostředek anglického jazyka. Prostředky pro němčinu a španělštinu je možné vytvářet v samostatných souborech s následujícími datovými oddíly:

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

Pokud je název dat k dispozici, pojmenuje proměnnou (bez použití úvodního $výrazu), do které má být uložena hodnota datového příkazu. $name = data { ... } Konkrétně je ekvivalentem data name { ... }.

8.10 Definice funkcí

Syntaxe:

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

Popis:

Definice funkce určuje název funkce, filtru nebo pracovního postupu, který se definuje, a názvy jeho parametrů, pokud existují. Obsahuje také nulové nebo více příkazů, které jsou provedeny k dosažení účelu dané funkce.

Každá funkce je instance třídy System.Management.Automation.FunctionInfo.

8.10.1 Funkce filtru

Zatímco běžná funkce běží jednou v kanálu a přistupuje ke vstupní kolekci prostřednictvím $input, filtr je speciální druh funkce, která se provádí jednou pro každý objekt ve vstupní kolekci. Objekt, který se právě zpracovává, je k dispozici prostřednictvím proměnné $_.

Filtr bez pojmenovaných bloků (§8.10.7) je ekvivalentní funkci s blokem procesu, ale bez počátečního bloku nebo koncového bloku.

Zvažte následující definici a volání funkce filtru:

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

Každý filtr je instance třídy System.Management.Automation.FilterInfo (§4.5.11).

8.10.2 Pracovní funkce

Funkce pracovního postupu je jako běžná funkce s implementací definovanou sémantikou. Funkce pracovního postupu se přeloží na posloupnost aktivit Windows Workflow Foundation a provede se v modulu Windows Workflow Foundation.

8.10.3 Zpracování argumentů

Zvažte následující definici funkce s názvem Get-Power:

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

Tato funkce má dva parametry $base a $exponent. Obsahuje také sadu příkazů, které pro nezáporné exponentní hodnoty vypočítá $base^$exponent^ a vrátí výsledek volajícímu Get-Power.

Když skript, funkce nebo filtr zahájí provádění, každý parametr se inicializuje na odpovídající hodnotu argumentu. Pokud neexistuje žádný odpovídající argument a je zadána výchozí hodnota (§8.10.4), použije se tato hodnota; jinak se použije hodnota $null . Každý parametr je tedy nová proměnná stejně jako v případě, že byl inicializován přiřazením na začátku bloku skriptu.

Pokud parametr skriptu obsahuje omezení typu (například [long] a [int] výše), hodnota odpovídajícího argumentu se převede na tento typ, pokud je to nutné; jinak nedojde k žádnému převodu.

Když skript, funkce nebo filtr začne provádění, proměnná $args je v ní definována jako nekonkutrénované 1rozměrné pole, které obsahuje všechny argumenty, které nejsou vázané podle názvu nebo pozice, v lexikálním pořadí.

Zvažte následující definici funkce a volání:

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

Další informace o vazbě parametrů naleznete v § 8.14.

8.10.4 Inicializátory parametrů

Deklarace parametru p může obsahovat inicializátor, v takovém případě se hodnota inicializátoru používá k inicializaci p zadaného p není vázána na žádné argumenty volání.

Zvažte následující definici funkce a volání:

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 Omezení typu [switch]

Při předání parametru přepínače musí být odpovídající parametr v příkazu omezen přepínačem typu. Přepínač typu má dvě hodnoty, True a False.

Zvažte následující definici funkce a volání:

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 a funkce

Při použití skriptu, funkce nebo filtru v kanálu se do tohoto skriptu nebo funkce doručí kolekce hodnot. Skript, funkce nebo filtr získá přístup k této kolekci prostřednictvím enumerátoru $input (§2.3.2.2, §4.5.16), který je definován při zadávání do tohoto skriptu, funkce nebo filtru.

Zvažte následující definici funkce a volání:

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 Pojmenované bloky

Příkazy v rámci bloku skriptu můžou patřit do jednoho velkého nenázvového bloku nebo je lze distribuovat do jednoho nebo více pojmenovaných bloků. Pojmenované bloky umožňují vlastní zpracování kolekcí pocházejících z kanálů; pojmenované bloky lze definovat v libovolném pořadí.

Příkazy v počátečním bloku (tj. jeden označený jako začátek klíčového slova) se spustí jednou, než se doručí první objekt kanálu.

Příkazy v bloku procesu (tj. jeden označený procesem klíčového slova) se spouští pro každý objekt kanálu doručený. ($_ poskytuje přístup k aktuálnímu objektu zpracovávaným ze vstupní kolekce pocházející z kanálu.) To znamená, že pokud se prostřednictvím kanálu odešle kolekce nulových prvků, blok procesu se vůbec nespustí. Pokud je však skript nebo funkce volána mimo kontext kanálu, tento blok se spustí přesně jednou a $_ je nastaven na $null, protože neexistuje žádný aktuální objekt kolekce.

Příkazy v koncovém bloku (tj. jeden označený koncem klíčového slova) se spustí jednou po doručení posledního objektu kanálu.

8.10.8 dynamicParam block

Pododdíly §8.10 zatím řeší statické parametry, které jsou definovány jako součást zdrojového kódu. Dynamické parametry lze definovat také prostřednictvím dynamického blokuParam, jiného tvaru pojmenovaného bloku (§8.10.7), který je označen klíčovým slovem dynamicParam. Velká část tohoto stroje je definována.

Dynamické parametry jsou parametry rutiny, funkce, filtru nebo skriptu, které jsou k dispozici pouze za určitých podmínek. Jedním z takových případů je parametr Kódování rutiny Set-Item .

V bloku příkazů použijte příkaz if k určení podmínek, za kterých je parametr k dispozici ve funkci. Pomocí rutiny New-Object vytvořte objekt typu definovaného implementací k reprezentaci parametru a zadejte jeho název. Slouží New-Object také k vytvoření objektu jiného typu definovaného implementací, který představuje atributy definované implementací parametru.

Následující příklad ukazuje funkci se standardními parametry s názvem Name a Path a volitelný dynamický parametr s názvem DP1. Parametr DP1 je v sadě parametrů PSet1 a má typ Int32. Parametr DP1 je k dispozici ve funkci Sample pouze v případě, že hodnota parametru Path obsahuje "HKLM:", což znamená, že se používá v HKEY_LOCAL_MACHINE jednotce registru.

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

Typ použitý k vytvoření objektu, který představuje dynamický parametr, je System.Management.Automation.RuntimeDefinedParameter.

Typ použitý k vytvoření objektu představující atributy parametru je System.Management.Automation.ParameterAttribute.

Atributy definované implementací parametru zahrnují Povinné, Position a ValueFromPipeline.

8.10.9 param blok

Param-block poskytuje alternativní způsob deklarování parametrů. Například následující sady deklarací parametrů jsou ekvivalentní:

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

Param-block umožňuje seznam atributů v param-blocku, zatímco funkce-parametr-deklarace není.

Skript může mít blok param-block , ale ne deklaraci function-parameter-. Definice funkce nebo filtru může mít deklaraci parametru nebo param-block, ale ne obojí.

Uvažujte následující příklad:

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

Jeden parametr , $ComputerNamemá typ string[], je povinný a přebírá vstup z kanálu.

Viz §12.3.7 , kde najdete diskuzi o atributu Parametr a další příklady.

8.11 Paralelní příkaz

Syntaxe:

parallel-statement:
    *parallel* statement-block

Paralelní příkaz obsahuje nulové nebo více příkazů, které se spouští definovaným způsobem implementace.

Paralelní příkaz je povolen pouze v pracovním postupu (§8.10.2).

8.12 Příkaz sekvence

Syntaxe:

sequence-statement:
    *sequence* statement-block

Příkaz sekvence obsahuje nulové nebo více příkazů, které se spouští definovaným způsobem implementace.

Příkaz sekvence je povolen pouze v pracovním postupu (§8.10.2).

8.13 Inlinescript – příkaz

Syntaxe:

inlinescript-statement:
    inlinescript statement-block

Příkaz inlinescript obsahuje nulové nebo více příkazů, které se spouští definovaným způsobem implementace.

Vložený příkaz je povolen pouze v pracovním postupu (§8.10.2).

8.14 Vazby parametrů

Při vyvolání skriptu, funkce, filtru nebo rutiny může být každý argument vázán na odpovídající parametr podle pozice s prvním parametrem, který má nulu pozice.

Zvažte následující fragment definice funkce s názvem Get-Powera volání:

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

Při vyvolání skriptu, funkce, filtru nebo rutiny může být argument vázán na odpovídající parametr podle názvu. To se provádí pomocí parametru s argumentem, což je argument, který je názvem parametru s úvodní pomlčkou (-), následovanou přidruženou hodnotou pro tento argument. Použitý název parametru může mít libovolný pravopis nerozlišující velká a velká písmena a může použít libovolnou předponu, která jednoznačně určí odpovídající parametr. Při výběru názvů parametrů nepoužívejte názvy běžných parametrů.

Zvažte následující volání funkce 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

Na druhou stranu volá následující funkci.

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

musí používat parametry -side1 a -side2, protože neexistuje žádná předpona, která jednoznačně určuje parametr.

Stejný název parametru nelze použít několikrát s různými přidruženými hodnotami argumentů nebo bez ní.

Parametry mohou mít atributy (§12). Informace o jednotlivých atributech najdete v oddílech v §12.3. Informace o sadách parametrů naleznete v § 12.3.7.

Skript, funkce, filtr nebo rutina může přijímat argumenty prostřednictvím příkazového řádku vyvolání, z kanálu nebo z obou. Tady jsou kroky pro překlad vazby parametrů:

  1. Vytvoření vazby všech pojmenovaných parametrů a pak
  2. Vytvoření vazby pozičních parametrů a pak
  3. Vazba z kanálu podle hodnoty (§12.3.7) s přesnou shodou a pak
  4. Vazba z kanálu podle hodnoty (§12.3.7) s převodem
  5. Svázat z kanálu podle názvu (§12.3.7) s přesnou shodu a pak
  6. Vazba z kanálu podle názvu (§12.3.7) s převodem

Některé z těchto kroků zahrnují převod, jak je popsáno v §6. Sada převodů použitých v vazbě ale není úplně stejná jako u převodů jazyka. Konkrétně:

  • I když lze hodnotu $null přetypovat na bool, $null nesmí být vázána na bool.
  • Když se hodnota $null předá parametru přepínače pro rutinu, je považována za $true předanou. Při předání parametru přepínače pro funkci se však považuje za $false předaný.
  • Parametry typu bool nebo přepínače se můžou svázat pouze s číselnými nebo logickými argumenty.
  • Pokud typ parametru není kolekcí, ale argument je nějaký druh kolekce, není pokus o převod, pokud typ parametru není objekt nebo PsObject. (Hlavním bodem tohoto omezení je zakázat převod kolekce na parametr řetězce.) Jinak se pokusíte o obvyklé převody.

Pokud je typ parametru nebo ICollection<T>pouze IList tyto převody prostřednictvím konstruktoru, op_Implicit a op_Explicit se pokusíte. Pokud neexistují žádné takové převody, použije se speciální převod parametrů typu "kolekce", který zahrnuje IList, ICollection<T>a pole.

Poziční parametry preferují vazbu bez převodu typů, pokud je to možné. Třeba

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"