8. Declarações

8.1 Blocos e listas de declaração

Sintaxe:

Dica

A ~opt~ notação nas definições de sintaxe indica que a entidade lexical é opcional na sintaxe.

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

Descrição:

Uma declaração especifica algum tipo de ação que deve ser realizada. Salvo indicação em contrário dentro desta cláusula, as declarações são executadas por ordem lexical.

Um bloco de declaração permite que um conjunto de declarações seja agrupado numa única unidade sintática.

8.1.1 Declarações etiquetadas

Sintaxe:

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

Descrição:

Uma declaração de iteração (§8.4) ou uma declaração do interruptor (§8.6) podem ser precedidas imediatamente por uma etiqueta, etiqueta de declaração. Uma etiqueta de declaração é utilizada como alvo opcional de uma rutura (§8.5.1) ou continuar (§8.5.2) declaração. No entanto, uma etiqueta não altera o fluxo de controlo.

O espaço branco não é permitido entre o cólon (:) e o símbolo que o segue.

Exemplos:

: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 Valores de declaração

O valor de uma declaração é o conjunto cumulativo de valores que escreve para o oleoduto. Se a declaração escrever um único valor escalar, este é o valor da declaração. Se a declaração escrever múltiplos valores, o valor da afirmação é aquele conjunto de valores armazenados em elementos de uma matriz unidimensional não constrangida, na ordem em que foram escritos. Considere o exemplo seguinte:

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

Não há iterações do laço e nada está escrito para o oleoduto. O valor da declaração é $null.

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

Embora o laço itera cinco vezes nada está escrito para o oleoduto. O valor da declaração é $null.

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

O laço itera cinco vezes cada vez que escreve para o oleoduto o int valor $i. O valor da declaração é object[] de Comprimento 5.

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

Embora o laço itera cinco vezes nada está escrito para o oleoduto. O valor da declaração é $null.

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

O laço itera cinco vezes com cada valor a ser escrito na tubagem. O valor da declaração é object[] de Comprimento 5.

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

O laço itera uma vez. O valor da declaração é o com int o valor 2.

Aqui estão outros exemplos:

# 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 Declarações de gasodutos

Sintaxe:

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

Descrição:

reorientações é discutida em §7.12; a expressão de atribuição é discutida em §7.11; e o ponto de operador de invocação de comando (.) é discutido em §3.5.5. Para uma discussão de mapeamento argument-to-parâmetro em invocações de comando, consulte §8.14.

O primeiro comando num oleoduto é uma expressão ou uma invocação de comando. Tipicamente, uma invocação de comando começa com um nome de comando, que normalmente é um identificador nu. elementos de comando representa a lista de argumentos para o comando. Uma nova linha ou n emicolon sem paisagem termina um oleoduto.

Uma invocação de comando consiste no nome do comando seguido de zero ou mais argumentos. As regras que regem os argumentos são as seguintes:

  • Um argumento que não é uma expressão, mas que contém texto arbitrário sem espaço branco não paisagista, é tratado como se fosse duplamente citado. O caso da carta está preservado.

  • A substituição variável e a expansão da subexexição (§2.3.5.2) ocorre no interior expansível-string-literal s e expansível-aqui-cordas-literal s.

  • As cotações internas do texto permitem que o espaço em branco, de ponta e incorporado, seja incluído no valor do argumento. [Nota: A presença de espaço branco num argumento citado não transforma um único argumento em múltiplos argumentos. nota final]

  • Colocar parênteses em torno de um argumento faz com que essa expressão seja avaliada com o resultado a ser aprovado em vez do texto da expressão original.

  • Para passar um argumento que se parece com um parâmetro de comutação (§2.3.4) mas que não se destina a tal, encerra esse argumento em aspas.

  • Ao especificar um argumento que corresponda a um parâmetro com a restrição do [switch] tipo (§8.10.5), a presença do nome do argumento por si só faz com que esse parâmetro seja definido para $true. No entanto, o valor do parâmetro pode ser explicitamente definido através da fixação de um sufixo ao argumento. Por exemplo, dado um parâmetro de tipo restrito p, um argumento de -p:$true conjuntos p para Verdadeiro, enquanto -p:$false define p para Falso.

  • Um argumento -- indica que todos os argumentos que o seguem devem ser transmitidos na sua forma real como se fossem colocadas citações duplas à sua volta.

  • Um argumento indica --% que todos os argumentos que o seguem devem ser aprovados com a mínima análise e processamento. Este argumento chama-se parâmetro verbatim. Os argumentos após o parâmetro verbatim não são expressões PowerShell mesmo que sejam expressões PowerShell válidas sintaticamente.

Se o tipo de comando for Aplicação, o parâmetro --% não é passado para o comando. Os argumentos depois --% têm quaisquer variáveis ambientais (cordas rodeadas por %) expandidas. Por exemplo:

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

A ordem de avaliação dos argumentos não é especificada.

Para obter informações sobre a ligação dos parâmetros consulte §8.14. Para obter informações sobre a procura de nomes consulte §3.8.

Uma vez concluído o processamento de argumentos, o comando é invocado. Se o comando invocado terminar normalmente (§8.5.4), o controlo reverte para o ponto no script ou função imediatamente após a invocação do comando. Para uma descrição do comportamento na rescisão anormal ver break (§8.5.1), continue (§8.5.2), throw (§8.5.3), exit (§8.5.5), try (§8.7) e trap (§8.8).

Normalmente, um comando é invocado usando o seu nome seguido por quaisquer argumentos. No entanto, o operador de invocação de comando, &, pode ser utilizado. Se o nome de comando contiver espaço branco não paisagístico, deve ser citado e invocado com este operador. Como um bloco de scripts não tem nome, também deve ser invocado com este operador. Por exemplo, as seguintes invocações de uma chamada Get-Factorial de comando são equivalentes:

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

São permitidas chamadas de funções recursivas diretas e indiretas. Por exemplo,

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

Exemplos:

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 A declaração se afirmação

Sintaxe:

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

Descrição:

As expressões de controlo do gasoduto devem ter um tipo de bool ou ser implicitamente convertíveis a esse tipo. A outra cláusula é opcional. Pode haver zero ou mais cláusulas.

Se o gasoduto de nível superior testar True, então o seu bloco de declaração é executado e a execução da declaração termina. Caso contrário, se uma outra cláusula estiver presente, se o seu pipeline testar True, então o seu bloco de declaração é executado e a execução da declaração termina. Caso contrário, se uma outra cláusula estiver presente, o seu bloco de declaração é executado.

Exemplos:

$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 Declarações de iteração

8.4.1 A declaração enquanto

Sintaxe:

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

while-condition:
    new-lines~opt~ pipeline

Descrição:

A expressão de controlo enquanto condição deve ter tipo bool ou ser implicitamente convertível a esse tipo. O corpo em loop, que consiste em bloco de declaração, é executado repetidamente até que a expressão de controlo testa falso. A expressão de controlo é avaliada antes de cada execução do corpo em loop.

Exemplos:

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

8.4.2 A declaração do do

Sintaxe:

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

Descrição:

A expressão de controlo enquanto condição deve ter tipo bool ou ser implicitamente convertível a esse tipo. Na forma enquanto, o corpo em loop, que consiste em bloco de declaração, é executado repetidamente enquanto a expressão controladora testa True. Na forma até, o corpo do loop é executado repetidamente até que a expressão de controlo testes Verdadeiros. A expressão de controlo é avaliada após cada execução do corpo em loop.

Exemplos:

$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 A declaração

Sintaxe:

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

Descrição:

A expressão de controlo para a condição deve ter tipo bool ou ser implicitamente convertível a esse tipo. O corpo em loop, que consiste em bloco de declaração, é executado repetidamente enquanto a expressão controladora testa True. A expressão de controlo é avaliada antes de cada execução do corpo em loop.

A expressão para o inicializador é avaliada antes da primeira avaliação da expressão de controlo. A expressão para o inicializador é avaliada apenas para os seus efeitos secundários; Qualquer valor que produz seja descartado e não esteja escrito ao oleoduto.

A expressão para iterador é avaliada após cada execução do corpo em loop. A expressão para iterador é avaliada apenas pelos seus efeitos secundários; Qualquer valor que produz seja descartado e não esteja escrito ao oleoduto.

Se a expressão para a condição for omitida, a expressão de controlo testa True.

Exemplos:

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 A declaração de primeiro-estar

Sintaxe:

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

Descrição:

O corpo em loop, que consiste em bloco de declaração, é executado para cada elemento designado pela variável variável na coleção designada por gasoduto. O âmbito da variável não se limita à declaração de proa. Como tal, mantém o seu valor final após o corpo do loop ter terminado a execução. Se o gasoduto designar um escalar (excluindo o valor $null) em vez de uma coleção, esse scalar é tratado como uma coleção de um elemento. Se o gasoduto designar o valor $null, o gasoduto é tratado como uma coleção de elementos zero.

Se o parâmetro -parallel do foreach for especificado, o comportamento é definido.

O parâmetro ‑parallel de foreach só é permitido num fluxo de trabalho (§8.10.2).

Cada declaração de primeiro plano tem o seu próprio enumerador($foreach§2.3.2.2, §4.5.16), que só existe enquanto esse ciclo está a executar.

Os objetos produzidos por gasoduto são recolhidos antes de o bloco de declaração começar a ser executado. No entanto, com o cmdlet ForEach-Object , o bloco de declaração é executado em cada objeto à medida que é produzido.

Exemplos:

$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 declarações de controlo Flow

Sintaxe:

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

Descrição:

Uma declaração de controlo de fluxo causa uma transferência incondicional de controlo para outro local.

8.5.1 A declaração de rutura

Descrição:

Uma declaração de rutura com uma expressão de rótulo é referida como uma declaração de rutura rotulada. Uma declaração de rutura sem uma expressão de rótulo é referida como uma declaração de rutura não marcada.

Fora de uma declaração de armadilha, uma declaração de rutura não identificada diretamente dentro de uma declaração de iteração (§8.4) termina a execução dessa menor declaração de iteração. Uma declaração de rutura não identificada diretamente dentro de uma declaração do interruptor (§8.6) termina a correspondência padrão para a condição de comutação do comutador atual. Consulte (§8.8) para obter informações sobre a utilização de uma rutura dentro de uma declaração de armadilha.

Uma declaração de iteração ou uma declaração de comutação podem ser precedidas imediatamente por uma etiqueta de declaração (§8.1.1). Esse rótulo de declaração pode ser utilizado como alvo de uma declaração de rutura rotulada, caso em que a declaração encerra a execução da declaração de iteração visada.

Uma rutura rotulada não precisa de ser resolvida em qualquer âmbito local; a procura de uma etiqueta correspondente pode continuar até a pilha de chamadas mesmo através dos limites do script e da chamada de função. Se não for encontrada uma etiqueta correspondente, a invocação de comando atual é terminada.

O nome do rótulo designado por expressão de etiqueta não precisa de ter um valor constante.

Se a expressão de rótulo for uma expressão não-ária, é convertida em uma corda.

Exemplos:

$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 A declaração continuada

Descrição:

Uma continue declaração com uma expressão de rótulo é referida como uma declaração continuada rotulada. Uma declaração continuada sem uma expressão de rótulo é referida como uma declaração continuada sem rótulo.

A utilização de dentro de continue uma declaração de armadilha é discutida em §8.8.

Uma declaração não identificada continue dentro de um ciclo termina a execução do loop atual e transfere o controlo para o suporte de fecho da menor declaração de iteração (§8.4). Uma declaração não identificada continue dentro de um interruptor termina a execução da iteração atual switch e transfere o controlo para a switchmenor condição de comutação (§8.6).

Uma declaração de iteração ou uma switch declaração (§8.6) pode ser precedida imediatamente por uma etiqueta de declaração (§8.1.1). Esse rótulo de declaração pode ser utilizado como alvo de uma declaração rotulada continue em anexo, caso em que a declaração encerra a execução do ciclo ou switch iteração atual, e transfere o controlo para a iteração ou switch o rótulo de declaração visado.

Uma etiqueta não continue precisa de ser resolvida em qualquer âmbito local; a procura de uma etiqueta correspondente pode continue subir a pilha de chamadas mesmo através dos limites do script e da chamada de função. Se não for encontrada uma etiqueta correspondente, a invocação de comando atual é terminada.

O nome do rótulo designado por expressão de etiqueta não precisa de ter um valor constante.

Se a expressão de rótulo for uma expressão não-ária, é convertida em uma corda.

Exemplos:

$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 A declaração de lançamento

Descrição:

Uma exceção é uma forma de lidar com uma condição de erro de nível de sistema ou aplicação. A declaração de lançamento levanta uma exceção. (Ver §8.7 para uma discussão sobre o tratamento de exceções.)

Se o gasoduto for omitido e a declaração de lançamento não estiver numa cláusula de captura, o comportamento é definido. Se o gasoduto estiver presente e a declaração de lançamento se encontra numa cláusula de captura, a exceção que foi apanhada por essa cláusula de captura é relançada após a execução de qualquer cláusula de captura finalmente associada à cláusula de captura .

Se o gasoduto estiver presente, o tipo de exceção lançada é definido.

Quando uma exceção é lançada, o controlo é transferido para a primeira cláusula de captura numa declaração de tentativa que pode lidar com a exceção. O local onde a exceção é lançada inicialmente é chamado de ponto de lançamento. Uma vez lançada uma exceção, os passos descritos no §8.7 são seguidos repetidamente até que uma cláusula de captura que corresponda à exceção seja encontrada ou nenhuma possa ser encontrada.

Exemplos:

throw
throw 100
throw "No such record in file"

Se o gasoduto for omitido e a declaração de lançamento não for de dentro de uma cláusula de captura, o texto "ScriptHalted" é escrito para o gasoduto, e o tipo de exceção levantada é System.Management.Automation.RuntimeException.

Se o gasoduto estiver presente, a exceção levantada é embrulhada num objeto do tipo System.Management.Automation.RuntimeException, que inclui informações sobre a exceção como System.Management.Automation.ErrorRecord objeto (acessível via $_).

Exemplo 1: throw 123 resulta numa exceção do tipo RuntimeException. De dentro do bloco de captura, $_.TargetObject contém o objeto embrulhado no interior, neste caso, um System.Int32 com o valor 123.

Exemplo 2: throw "xxx" resulta numa exceção do tipo RuntimeException. De dentro do bloco de captura, $_.TargetObject contém o objeto embrulhado no interior, neste caso, um System.String com valor "xxx".

Exemplo 3: throw 10,20 resulta numa exceção do tipo RuntimeException. De dentro do bloco de capturas, $_.TargetObject contém o objeto embrulhado no interior, neste caso, um System.Object[]conjunto de dois elementos sem restrições com o System. Valores int32' 10 e 20.

8.5.4 Declaração de devolução

Descrição:

A return declaração escreve ao pipeline os valores designados por pipeline, se houver, e devolve o controlo à função ou ao autor da chamada do script. Uma função ou script pode ter zero ou mais return declarações.

Se a execução atingir o suporte de fecho de uma função, return é assumido um implícito sem gasoduto .

A return afirmação é um pouco de "açúcar sintático" para permitir que os programadores se expressem como podem noutras línguas; no entanto, o valor devolvido de uma função ou script é, na verdade, todos os valores escritos ao pipeline por essa função ou script mais qualquer valor especificado por pipeline. Se apenas um valor escalar for escrito ao gasoduto, o seu tipo é o tipo de valor devolvido; caso contrário, o tipo de retorno é uma matriz unidimensional não constrangida que contém todos os valores escritos para o oleoduto.

Exemplos:

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

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

O chamador recebe Get-Factorial um 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
}

O chamador recebe Test de volta uma matriz de 1 dimensão não-constrangida de três elementos.

8.5.5 A declaração de saída

Descrição:

A declaração de saída termina o script atual e devolve o controlo e um código de saída para o ambiente de anfitrião ou para o script de chamada. Se o gasoduto for fornecido, o valor que designa é convertido para int, se necessário. Se não existir tal conversão, ou se o gasoduto for omitido, o valor int zero é devolvido.

Exemplos:

exit $count # terminate the script with some accumulated count

8.6 A declaração do interruptor

Sintaxe:

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

Descrição:

Se a condição de comutação designar um único valor, o controlo é passado para um ou mais blocos de declaração de padrão correspondentes. Se nenhum padrão coincidir, podem ser tomadas algumas medidas padrão.

Um interruptor deve conter uma ou mais cláusulas de comutação, cada uma começando com um padrão (uma cláusula de comutação não padrão), ou a palavra-chavedefault (uma cláusula de comutação padrão). Um interruptor deve conter cláusulas de comutação zero ou uma default e cláusulas de comutação zero ou mais não padrão. As cláusulas de comutação podem ser escritas em qualquer ordem.

Vários padrões podem ter o mesmo valor. Um padrão não precisa ser literal, e um interruptor pode ter padrões com diferentes tipos.

Se o valor da condição de comutação corresponder a um valor de padrão, o bloco de declaração desse padrão é executado. Se vários valores de padrão corresponderem ao valor da condição de comutação, o bloco de declaração de cada padrão de correspondência é executado, por ordem lexical, a menos que qualquer um desses blocos de declaração contenha uma break declaração (§8.5.1).

Se o valor da condição de comutação não corresponder a qualquer valor de padrão, se existe uma default cláusula de comutação, o seu bloco de declaração é executado; caso contrário, o padrão correspondente a essa condição de comutação é terminado.

Os interruptores podem ser aninhados, com cada interruptor a ter o seu próprio conjunto de cláusulas de comutação. Nesses casos, uma cláusula de comutação pertence ao interruptor mais íntimo atualmente no âmbito.

Na entrada de cada bloco de declaração, $_ é automaticamente atribuído o valor da condição de comutação que fez com que o controlo fosse para esse bloco de afirmação. $_ também está disponível na condição de cláusula de comutação do bloco de declaração.

A correspondência de não-cordas é feita através de testes para a igualdade (§7.8.1).

Se a correspondência envolve cordas, por defeito, a comparação é insensata em caso. A presença do parâmetro -casesensitive de comutação torna a comparação sensível ao caso.

Um padrão pode conter caracteres wildcard (§3.15), neste caso, são realizadas comparações de cordas wildcard, mas apenas se o parâmetro-parâmetro do switch -wildcard estiver presente. Por defeito, a comparação é insensível a caso.

Um padrão pode conter uma expressão regular (§3.16), caso em que são realizadas comparações regulares de cordas de expressão, mas apenas se o parâmetro -regex do comutador estiver presente. Por defeito, a comparação é insensível a caso. Se -regex estiver presente e um padrão for igualado, $matches é definido no bloco de declaração da cláusula de comutação para esse padrão.

Um parâmetro de comutação pode ser abreviado; pode ser utilizada qualquer parte principal distinta de um parâmetro. Por exemplo, ‑regexe ‑rege``‑reg``‑re``‑r são equivalentes.

Se forem especificados parâmetros de comutação contraditórios, o lexicamente final prevalece. A presença de ‑exact deficientes -regex e -wildcard; não tem qualquer efeito sobre , no ‑caseentanto.

Se o parâmetro ‑parallel de comutação for especificado, o comportamento é definido.

O parâmetro ‑parallel de comutação só é permitido num fluxo de trabalho (§8.10.2).

Se um padrão é uma expressão de bloco de script, esse bloco é avaliado e o resultado é convertido em bool, se necessário. Se o resultado tiver o valor $true, o bloco de declaração correspondente é executado; caso contrário, não é.

Se a condição de comutação designar vários valores, o comutador é aplicado a cada valor na ordem lexical utilizando as regras acima descritas para uma condição de comutação que designa um único valor. Cada declaração do switch tem o seu próprio enumerador ($switch§2.3.2.2, §4.5.16), que só existe enquanto o interruptor está a ser executado.

Uma declaração do interruptor pode ter uma etiqueta, podendo conter rutura rotulada e sem rótulo (§8.5.1) e continuar (§8.5.2) declarações .

Se a condição de comutação for -file o nome de comutador, em vez de iterar sobre os valores numa expressão, o interruptor imita sobre os valores no ficheiro designado por nome de comutador. O ficheiro é lido uma linha de cada vez com cada linha que inclui um valor. Os caracteres exterminadores de linha não estão incluídos nos valores.

Exemplos:

$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 A afirmação de tentativa/finalmente

Sintaxe:

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

Descrição:

A declaração de tentativa fornece um mecanismo para capturar exceções que ocorrem durante a execução de um bloco. A declaração de tentativa também fornece a capacidade de especificar um bloco de código que é sempre executado quando o controlo deixa a declaração de tentativa. O processo de levantamento de uma exceção através da declaração de lançamento é descrito em §8.5.3.

Um bloco de tentativa é o bloco de declaração associado à declaração de tentativa. Um bloco de capturas é o bloco de declaração associado a uma cláusula de captura. Um bloco finalmente é o bloco de declarações associado a uma cláusula finalmente.

Uma cláusula de captura sem uma lista de capturas chama-se cláusula geral de captura.

Cada cláusula de captura é um manipulador de exceções, e uma cláusula de captura cuja lista de capturas contém o tipo de exceção levantada é uma cláusula de captura correspondente. Uma cláusula geral de captura corresponde a todos os tipos de exceções.

Embora as cláusulas de captura e , finalmente, a cláusula sejam facultativas, pelo menos uma delas deve estar presente.

O tratamento de uma exceção arremessada consiste em avaliar repetidamente os seguintes passos até que seja encontrada uma cláusula de captura que corresponda à exceção.

  • No âmbito atual, cada declaração de tentativa que encerra o ponto de lançamento é examinada. Para cada declaração de tentativa S, começando com a declaração de tentativa mais interna e terminando com a declaração de tentativa mais externa, são avaliados os seguintes passos:

    • Se o try bloco de S encerrar o ponto de lançamento e se S tiver uma ou mais cláusulas de captura, as cláusulas de captura são examinadas de forma lexical para localizar um manipulador adequado para a exceção. A primeira cláusula de captura que especifica o tipo de exceção ou um tipo base do tipo de exceção é considerada uma correspondência. Uma cláusula geral de captura é considerada uma correspondência para qualquer tipo de exceção. Se for localizada uma cláusula de captura correspondente, o tratamento de exceção é concluído transferindo o controlo para o bloco dessa cláusula de captura. Dentro de uma cláusula de captura correspondente, a variável $_ contém uma descrição da exceção atual.

    • Caso contrário, se o try bloco ou um catch bloco de S encerrar o ponto de lançamento e se S tiver um finally bloco, o controlo é transferido para o bloco finalmente. Se o finally bloco lançar outra exceção, o processamento da exceção atual é encerrado. Caso contrário, quando o controlo chega ao fim do finally bloco, o processamento da atual exceção é continuado.

  • Se um manipulador de exceções não se situar no âmbito atual, os passos acima referidos são então repetidos para o âmbito de enclosão com um ponto de lançamento correspondente à declaração a partir da qual o âmbito atual foi invocado.

  • Se o processamento de exceção acabar por terminar todos os âmbitos, indicando que não existe nenhum manipulador para a exceção, então o comportamento não é especificado.

Para evitar cláusulas de captura inalcançáveis num bloco de tentativa, uma cláusula de captura não pode especificar um tipo de exceção igual ou derivado de um tipo que foi especificado numa cláusula de captura anterior dentro desse mesmo bloco de tentativa.

As declarações de um finally bloco são sempre executadas quando o controlo deixa uma try declaração. Isto é verdade se a transferência de controlo ocorre como resultado de uma execução normal, em resultado da execução de uma break, continueou return declaração, ou como resultado de uma exceção ser expulso da try declaração.

Se for lançada uma exceção durante a execução de um finally bloco, a exceção é lançada para a próxima try declaração. Se outra exceção estivesse em vias de ser tratada, essa exceção é perdida. O processo de geração de uma exceção é ainda discutido na descrição da throw declaração.

try as declarações podem coexistir com trap declarações; ver §8.8 para mais detalhes.

Exemplos:

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

Cada exceção lançada é levantada como um System.Management.Automation.RuntimeException. Se houver cláusula de captura específica no try bloco, a propriedade InnerException da exceção é inspecionada para tentar encontrar uma correspondência, como é o caso do tipo System.IndexOutOfRangeException acima.

8.8 A declaração de armadilha

Sintaxe:

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

Descrição:

Uma trap declaração com e sem tipo literal é análoga a um catch bloco (§8.7) com e sem lista de capturas, respectivamente, exceto que uma trap declaração só pode prender um tipo de cada vez.

Várias trap declarações podem ser definidas no mesmo bloco de declaração, e a sua ordem de definição é irrelevante. Se duas trap declarações com o mesmo tipo-literal forem definidas no mesmo âmbito, a primeira lexicamente é usada para processar uma exceção do tipo de correspondência.

Ao contrário de um catch bloco, uma trap declaração corresponde exatamente a um tipo de exceção; não é realizada qualquer correspondência de tipo derivado.

Quando ocorre uma exceção, se não houver nenhuma declaração correspondente trap no âmbito atual, é procurada uma declaração de armadilha correspondente no âmbito de encerramento, o que pode implicar olhar para o script, função ou filtro de chamada, e depois no seu chamador, e assim por diante. Se a procura acabar por terminar todos os âmbitos, indicando que não existe nenhum manipulador para a exceção, então o comportamento não é especificado.

O trap corpo de declaração de uma declaração só executa para processar a exceção correspondente; caso contrário, a execução passa por cima dela.

Se um trap' corpo de declaração sair normalmente, por defeito, um objeto de erro é escrito para o fluxo de erro, a exceção é considerada manuseada, e a execução continua com a declaração imediatamente a seguir à declaração no âmbito que contém a trap declaração que tornou visível a exceção. A causa da exceção pode estar num comando chamado pelo comando que contém a trap declaração.

Se a declaração final executada num trap' corpo de declaração' for continuada (§8.5.2), a redação do objeto de erro no fluxo de erro é suprimida e a execução prossegue com a declaração imediatamente a seguir à declaração no âmbito que contém a declaração de armadilha que tornou visível a exceção. Se a declaração final executada num trapcorpo de declaração for rutura (§8.5.1), a redação do objeto de erro no fluxo de erro é suprimida e a exceção é relançada.

trap Numa declaração, a variável $_ contém uma descrição do erro atual.

Considere o caso em que uma exceção levantada dentro de um try bloco não tem um bloco correspondente catch , mas existe uma declaração correspondente trap a um nível de bloco mais alto. Após a try cláusula do bloco ser executada, a trap declaração fica controlada mesmo que qualquer âmbito de pai tenha um bloco correspondente catch . Se uma trap declaração for definida dentro do try próprio bloco, e esse try bloco tiver um bloco correspondente catch , a trap declaração fica controlada.

Exemplos:

No exemplo seguinte, o objeto de erro é escrito e a execução prossegue com a declaração imediatamente a seguir à que causou a armadilha; isto é, "Feito" é escrito para o oleoduto.

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

No exemplo seguinte, a escrita do objeto de erro é suprimida e a execução prossegue com a declaração imediatamente a seguir à que causou a armadilha; isto é, "Feito" é escrito para o oleoduto.

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

No exemplo seguinte, a escrita do objeto de erro é suprimida e a exceção é relançada.

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

No exemplo seguinte, as declarações de armadilha e de exceção estão no mesmo âmbito. Após a exceção ser apanhada e tratada, a execução retoma com a escrita 1 para o oleoduto.

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

No exemplo seguinte, as declarações de armadilha e de exceção são em diferentes âmbitos. Após a exceção ser capturada e manuseada, a execução retoma com a escrita 2 (não 1) para o gasoduto.

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

8.9 A declaração de dados

Sintaxe:

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

Descrição:

Uma declaração de dados cria uma secção de dados, mantendo os dados dessa secção separados do código. Esta separação suporta instalações como ficheiros de recursos de cadeia separados para texto, tais como mensagens de erro e cadeias de ajuda. Também ajuda a apoiar a internacionalização, facilitando a isolar, localizar e processar cordas que serão traduzidas em diferentes línguas.

Um script ou função pode ter zero ou mais secções de dados.

O bloco de declaração de uma secção de dados limita-se apenas a conter as seguintes funcionalidades PowerShell:

  • Todos os operadores, exceto -match
  • A if declaração
  • As seguintes variáveis automáticas: , , , e $null``$false. $true``$PsUICulture``$PsCulture
  • Comentários
  • Pipelines
  • Declarações separadas por pontos-e-vírguis (;)
  • Literais
  • Chamadas para o cmdlet ConvertFrom-StringData
  • Quaisquer outros cmdlets identificados através do parâmetro composições suportados

Se o ConvertFrom-StringData cmdlet for utilizado, os pares chave/valor podem ser expressos utilizando qualquer forma de corda literal. No entanto, o expandível-string-literal s e expansível-aqui-string-literal s não deve conter quaisquer substituições variáveis ou expansões de sub-expressão.

Exemplos:

O parâmetro Suportado com oCommand indica que os cmdlets ou funções emitidos geram apenas dados. Por exemplo, a seguinte secção de dados inclui um cmdlet escrito pelo utilizador, ConvertTo-XMLque forma os dados num ficheiro XML:

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

Considere o exemplo a seguir, no qual a secção de dados contém um ConvertFrom-StringData comando que converte as cordas numa tabela de hash, cujo valor é atribuído a $messages.

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

As teclas e valores da tabela de hash são acedidos através de $messages.Greeting, $messages.Yese $messages.No, respectivamente.

Isto pode ser guardado como um recurso em língua inglesa. Os recursos em língua alemã e espanhola podem ser criados em ficheiros separados, com as seguintes secções de dados:

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

Se o dataname estiver presente, ele nomeia a variável (sem usar uma liderança $) na qual o valor da declaração de dados deve ser armazenado. Especificamente, $name = data { ... } é equivalente a data name { ... }.

8.10 Definições de função

Sintaxe:

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

Descrição:

Uma definição de função especifica o nome da função, filtro ou fluxo de trabalho que está a ser definido e os nomes dos seus parâmetros, se houver. Também contém zero ou mais declarações que são executadas para atingir o propósito dessa função.

Cada função é um exemplo da classe System.Management.Automation.FunctionInfo.

8.10.1 Funções de filtro

Enquanto uma função comum funciona uma vez num oleoduto e acede à recolha de entradas através $inputde, um filtro é um tipo especial de função que executa uma vez por cada objeto na recolha de entradas. O objeto atualmente em processo está disponível através da variável $_.

Um filtro sem blocos nomeados (§8.10.7) é equivalente a uma função com um bloco de processo, mas sem qualquer bloco de início ou bloco final.

Considere a seguinte definição de função de filtro e chamadas:

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

Cada filtro é um exemplo da classe System.Management.Automation.FilterInfo (§4.5.11).

8.10.2 Funções de fluxo de trabalho

Uma função de fluxo de trabalho é como uma função comum com semântica definida de implementação. Uma função de fluxo de trabalho é traduzida para uma sequência de atividades da Fundação Windows workflow e executada no motor Windows Workflow Foundation.

8.10.3 Processamento de argumentos

Considere a seguinte definição para uma função chamada Get-Power:

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

Esta função tem dois parâmetros, $base e $exponent. Contém também um conjunto de declarações que, para valores não negativos $base^$exponent^ de expoentes, calcula e devolve o resultado ao Get-Powerchamador.

Quando um script, função ou filtro começa a execução, cada parâmetro é inicializado ao valor do seu argumento correspondente. Se não houver argumento correspondente e for fornecido um valor predefinido (§8.10.4), esse valor é utilizado; caso contrário, o valor $null é usado. Como tal, cada parâmetro é uma nova variável como se tivesse sido inicializada por atribuição no início do script-block.

Se um parâmetro de script contiver uma restrição de tipo (como [long] e [int] acima), o valor do argumento correspondente é convertido para esse tipo, se necessário; caso contrário, não ocorre conversão.

Quando um script, função ou filtro começa a execução, a variável $args é definida dentro dela como uma matriz unidimensional não limitada, que contém todos os argumentos não ligados pelo nome ou posição, em ordem lexical.

Considere a seguinte definição de função e chamadas:

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

Para obter mais informações sobre a ligação dos parâmetros consulte §8.14.

8.10.4 Inicializadores de parâmetros

A declaração de um parâmetro p pode conter um inicializador, caso em que o valor do inicializador é utilizado para inicializar p desde que p não esteja ligado a quaisquer argumentos na chamada.

Considere a seguinte definição de função e chamadas:

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 A restrição do tipo [switch]

Quando um parâmetro de comutação é passado, o parâmetro correspondente no comando deve ser limitado pelo interruptor de tipo. O interruptor de tipo tem dois valores, Verdadeiro e Falso.

Considere a seguinte definição de função e chamadas:

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 Oleodutos e funções

Quando um script, função ou filtro é usado num oleoduto, uma coleção de valores é entregue a esse script ou função. O script, função ou filtro obtém acesso a essa coleção através do $input enumerador (§2.3.2.2, §4.5.16), que é definido à entrada para esse script, função ou filtro.

Considere a seguinte definição de função e chamadas:

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 Blocos nomeados

As declarações dentro de um bloco de script podem pertencer a um grande bloco sem nome, ou podem ser distribuídas em um ou mais blocos nomeados. Os blocos nomeados permitem o processamento personalizado de coleções provenientes de oleodutos; blocos nomeados podem ser definidos em qualquer ordem.

As declarações num bloco de início (ou seja, uma marcada com a palavra-chave em início) são executadas uma vez, antes de o primeiro objeto de pipeline ser entregue.

As declarações num bloco de processo (ou seja, uma marcada com o processo de palavra-chave) são executadas para cada objeto de pipeline entregue. ($_ dá acesso ao objeto atual que está a ser processado a partir da recolha de entradas proveniente do gasoduto.) Isto significa que se uma coleção de elementos zero for enviada através do oleoduto, o bloco de processo não é executado de todo. No entanto, se o script ou função for chamado fora de um contexto de pipeline, este bloco é executado exatamente uma vez, e $_ está definido para $null, uma vez que não existe nenhum objeto de coleção atual.

As declarações num bloco final (ou seja, uma marcada com a ponta da palavra-chave) são executadas uma vez, após a entrega do último objeto do gasoduto.

8.10.8 dinâmico Bloco de combate a uma manhã

As subsecções de §8.10 até agora tratam de parâmetros estáticos, que são definidos como parte do código fonte. Também é possível definir parâmetros dinâmicos através de um bloco dinâmicoParam, outra forma de bloco nomeado (§8.10.7), que é marcado com a palavra-chave dynamicParam. Grande parte desta maquinaria está definida.

Parâmetros dinâmicos são parâmetros de um cmdlet, função, filtro ou script que estão disponíveis apenas em determinadas condições. Um desses casos é o parâmetro de codificação do Set-Item cmdlet.

No bloco de declaração, utilize uma declaração para especificar as condições em que o parâmetro está disponível na função. Utilize o cmdlet New-Object para criar um objeto de um tipo definido para a implementação para representar o parâmetro e especificar o seu nome. Além disso, utilize New-Object para criar um objeto de um tipo diferente definido para implementação para representar os atributos definidos pela implementação do parâmetro.

O exemplo a seguir mostra uma função com parâmetros padrão chamado Nome e Caminho, e um parâmetro dinâmico opcional chamado DP1. O parâmetro DP1 está no conjunto de parâmetros PSet1 e tem um tipo de Int32. O parâmetro DP1 só está disponível na função Amostra quando o valor do parâmetro Path contiver "HKLM:", indicando que está a ser utilizado na unidade de HKEY_LOCAL_MACHINE registo.

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

O tipo usado para criar um objeto para representar um parâmetro dinâmico é System.Management.Automation.RuntimeDefinedParameter.

O tipo utilizado para criar um objeto para representar os atributos do parâmetro é System.Management.Automation.ParameterAttribute.

Os atributos definidos pela implementação do parâmetro incluem Mandatory, Position e ValueFromPipeline.

Bloco de param de 8.10.9

Um bloco de param fornece uma forma alternativa de declarar parâmetros. Por exemplo, os seguintes conjuntos de declarações de parâmetros são equivalentes:

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

Um param-block permite uma lista de atributos no bloco de param, enquanto uma declaração de parâmetro de função não.

Um script pode ter um param-block , mas não uma declaração de parâmetro de função. Uma definição de função ou filtro pode ter uma declaração de parâmetro de função ou um param-block, mas não ambos.

Considere o exemplo seguinte:

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

O parâmetro, $ComputerNametem tipo string[], é necessário, e requer a entrada do gasoduto.

Consulte §12.3.7 para uma discussão sobre o atributo Parâmetro e para mais exemplos.

8.11 A declaração paralela

Sintaxe:

parallel-statement:
    *parallel* statement-block

A declaração paralela contém zero ou mais declarações que são executadas de forma definida na implementação.

Uma declaração paralela só é permitida num fluxo de trabalho (§8.10.2).

8.12 A declaração de sequência

Sintaxe:

sequence-statement:
    *sequence* statement-block

A declaração de sequência contém zero ou mais declarações que são executadas de forma definida na implementação.

Uma declaração de sequência só é permitida num fluxo de trabalho (§8.10.2).

8.13 A declaração inlinescript

Sintaxe:

inlinescript-statement:
    inlinescript statement-block

A declaração inlinescript contém zero ou mais declarações que são executadas de forma definida como implementação.

Uma declaração inlinescript só é permitida num fluxo de trabalho (§8.10.2).

8.14 Ligação para parâmetros

Quando um script, função, filtro ou cmdlet são invocados, cada argumento pode ser ligado ao parâmetro correspondente por posição, com o primeiro parâmetro com a posição zero.

Considere o seguinte fragmento de definição para uma função chamada Get-Power, e as chamadas para ele:

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

Quando um script, função, filtro ou cmdlet são invocados, um argumento pode ser ligado ao parâmetro correspondente pelo nome. Isto é feito usando um parâmetro com argumento, que é um argumento que é o nome do parâmetro com um traço principal (-), seguido pelo valor associado para esse argumento. O nome do parâmetro utilizado pode ter qualquer ortografia insensível a casos e pode usar qualquer prefixo que designe exclusivamente o parâmetro correspondente. Ao escolher nomes de parâmetros, evite usar os nomes dos parâmetros comuns.

Considere as seguintes chamadas para funcionar 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

Por outro lado, chama para a seguinte função

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

deve utilizar parâmetros -side1 e -side2, uma vez que não existe nenhum prefixo que designe exclusivamente o parâmetro.

O mesmo nome de parâmetro não pode ser usado várias vezes com ou sem valores de argumento associados diferentes.

Os parâmetros podem ter atributos (§12). Para obter informações sobre os atributos individuais consulte as secções dentro do §12.3. Para obter informações sobre os parâmetros consulte §12.3.7.

Um script, função, filtro ou cmdlet podem receber argumentos através da linha de comando de invocação, do oleoduto ou de ambos. Aqui estão os passos, a fim, para resolver a ligação dos parâmetros:

  1. Ligue todos os parâmetros nomeados, então
  2. Ligar parâmetros posicionais, então
  3. Ligar do oleoduto por valor (§12.3.7) com correspondência exata, em seguida,
  4. Ligar do gasoduto por valor (§12.3.7) com conversão, em seguida,
  5. Ligar do oleoduto pelo nome (§12.3.7) com correspondência exata, em seguida,
  6. Ligar do gasoduto por nome (§12.3.7) com conversão

Vários destes passos envolvem conversão, como descrito no §6. No entanto, o conjunto de conversões utilizadas na ligação não é exatamente o mesmo que o utilizado nas conversões linguísticas. Mais concretamente:

  • Embora o valor $null possa ser lançado para bool, $null não pode ser obrigado a bool.
  • Quando o valor $null é passado para um parâmetro de comutação para um cmdlet, é tratado como se $true tivesse sido passado. No entanto, quando passado para um parâmetro de comutação para uma função, é tratado como se $false tivesse sido passado.
  • Os parâmetros do tipo bool ou switch só podem ligar-se a argumentos numéricos ou bool.
  • Se o tipo de parâmetro não for uma coleção, mas o argumento for algum tipo de recolha, não é tentada qualquer conversão a menos que o tipo de parâmetro seja objeto ou PsObject. (O principal ponto desta restrição é não permitir a conversão de uma coleção para um parâmetro de corda.) Caso contrário, as conversões habituais são tentadas.

Se o tipo de parâmetro for IList ou ICollection<T>, apenas as conversões através de Construtor, op_Implicit e op_Explicit são tentadas. Se não existirem tais conversões, é utilizada uma conversão especial para parâmetros do tipo "coleção", que inclui IList, ICollection<T>e matrizes.

Os parâmetros posicionais preferem ser ligados sem conversão do tipo, se possível. Por exemplo,

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"