Compartilhar via


8. Declarações

Nota editorial

Importante

A Especificação da Linguagem do Windows PowerShell 3.0 foi publicada em dezembro de 2012 e é baseada no Windows PowerShell 3.0. Essa especificação não reflete o estado atual do PowerShell. Não há nenhum plano para atualizar essa documentação para refletir o estado atual. Esta documentação é apresentada aqui para referência histórica.

O documento de especificação está disponível como um documento do Microsoft Word do Centro de Download da Microsoft em: https://www.microsoft.com/download/details.aspx?id=36389 esse documento do Word foi convertido para apresentação aqui no Microsoft Learn. Durante a conversão, algumas alterações editoriais foram feitas para acomodar a formatação para a plataforma Docs. Alguns erros de digitação e pequenos foram corrigidos.

8.1 Blocos de declarações e listas

Sintaxe:

Dica

A notação ~opt~ 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 instrução especifica algum tipo de ação a ser executada. A menos que indicado de outra forma dentro dessa cláusula, as instruções são executadas em ordem lexical.

Um statement-block permite que um conjunto de instruções seja agrupado em uma única unidade sintática.

8.1.1 Instruções rotuladas

Sintaxe:

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

Descrição:

Uma instrução de iteração (§8.4) ou uma instrução switch (§8.6) pode ser precedida imediatamente por um rótulo de instrução, label. Um rótulo de instrução é usado como o destino opcional de uma instrução break (§8.5.1) ou continue (§8.5.2). No entanto, um rótulo não altera o fluxo de controle.

Não é permitido espaço em branco entre os dois-pontos (:) e o token 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) {
            # ...
        }
    }
}

Valores da declaração 8.1.2

O valor de uma instrução é o conjunto cumulativo de valores que ele grava no pipeline. Se a instrução gravar um único valor escalar, esse será o valor da instrução. Se a instrução gravar vários valores, o valor da instrução será aquele conjunto de valores armazenados em elementos de uma matriz unidimensional não restrita, na ordem em que foram gravados. Considere o seguinte exemplo:

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

Não há iterações do loop e nada é gravado no pipeline. O valor da instrução é $null.

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

Embora o loop itere cinco vezes, nada é gravado no pipeline. O valor da instrução é $null.

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

O loop é iterado cinco vezes a cada vez que se escreve no pipeline o valor int $i. O valor da instrução é object[] de comprimento 5.

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

Embora o loop itere cinco vezes, nada é gravado no pipeline. O valor da instrução é $null.

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

O loop é iterado cinco vezes com cada valor que está sendo gravado no pipeline. O valor da instrução é object[] de comprimento 5.

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

O loop é iterado uma vez. O valor da instrução é o int com valor 2.

Aqui estão alguns 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 Instruções de pipeline

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:

redirections são discutidos em §7.12; assignment-expression são discutidos em §7.11; e o command-invocation-operator dot (.) é discutido em §3.5.5. Para obter informações sobre o mapeamento de argumento para parâmetro em invocações de comando, consulte §8.14.

O primeiro comando em um pipeline é uma expressão ou uma invocação de comando. Normalmente, uma invocação de comando começa com um nome de comando , que geralmente é simplesmente um identificador. elementos de comando representa a lista de argumentos para o comando. Uma nova linha ou ponto e vírgula sem escape encerra um pipeline.

Uma invocação de comando consiste no nome do comando seguido por 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 em branco sem escape, é tratado como se estivesse entre aspas duplas. A distinção entre maiúsculas e minúsculas é preservada.

  • A substituição de variável e a expansão de subexpressão (§2.3.5.2) ocorrem dentro de expandable-string-literals e expandable-here-string-literals.

  • O texto entre aspas permite que espaços em branco à esquerda, à direita e incorporados sejam incluídos no valor do argumento. [Observação: a presença de espaço em branco em um argumento entre aspas não transforma um único argumento em vários argumentos. fim da observação]

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

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

  • Ao especificar um argumento que corresponde a um parâmetro com a restrição de tipo [switch] (§8.10.5), a presença do nome do argumento por conta própria faz com que esse parâmetro seja definido como $true. No entanto, o valor do parâmetro pode ser definido explicitamente acrescentando um sufixo ao argumento. Por exemplo, dado um parâmetro restrito de tipo p, um argumento de -p:$true define p como True, enquanto -p:$false define p como False.

  • Um argumento -- indica que todos os argumentos após ele devem ser passados em seu formato real, como se estivessem entre aspas duplas.

  • Um argumento de --% indica que todos os argumentos a seguir devem ser passados com análise e processamento mínimos. Esse argumento é chamado de parâmetro verbatim. Argumentos após o parâmetro verbatim não são expressões do PowerShell, mesmo que sejam expressões do PowerShell sintaticamente válidas.

Se o tipo de comando for Application, o parâmetro --% não será passado para o comando. Os argumentos depois de --% têm as variáveis de ambiente (cadeias de caracteres circundadas 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 associação de parâmetros, consulte §8.14. Para obter informações sobre pesquisa de nome, consulte §3.8.

Depois que o processamento de argumentos for concluído, o comando será invocado. Se o comando invocado terminar normalmente (§8.5.4), o controle será revertido para o ponto no script ou função imediatamente após a invocação de comando. Para obter uma descrição do comportamento na terminação anormal, consulte 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 seu nome seguido por quaisquer argumentos. No entanto, o operador de invocação de comando, &, pode ser usado. Se o nome do comando contiver espaço em branco sem escape, ele deverá ser citado e invocado com esse operador. Como um bloco de script não tem nome, ele também deve ser invocado com esse operador. Por exemplo, as seguintes invocações de uma chamada de comando Get-Factorial são equivalentes:

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

Chamadas de função recursiva diretas e indiretas são permitidas. 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 instrução if

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 controle do pipeline devem ter o tipo bool ou ser implicitamente conversíveis para esse tipo. A else-clause é opcional. Pode haver nenhuma ou mais else-clauses.

Se o pipeline de nível superior for True, seu statement-block será executado e a execução da instrução terminará. Caso contrário, se uma elseif-clause estiver presente, se o seu pipeline for True, seu statement-block será executado e a execução da instrução terminará. Caso contrário, se uma else-clause estiver presente, seu statement-block será 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 Instruções de iteração

8.4.1 A instrução while

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:

As expressões de controle while-condition devem ter o tipo bool ou ser implicitamente conversível para esse tipo. O corpo do loop, que consiste em statement-block, será executado repetidamente até que a expressão de controle seja False. A expressão de controle é avaliada antes de cada execução do corpo do 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 instrução 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:

As expressões de controle while-condition devem ter o tipo bool ou ser implicitamente conversível para esse tipo. Na forma while, o corpo do loop, que consiste em statement-block, será executado repetidamente enquanto a expressão de controle for True. Na forma until, o corpo do loop será executado repetidamente até que a expressão de controle seja True. A expressão de controle é avaliada após cada execução do corpo do 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 instrução for

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 controle para condição deve ter o tipo bool ou ser implicitamente conversível para esse tipo. O corpo do loop, que consiste em statement-block, será executado repetidamente enquanto a expressão de controle for True. A expressão de controle é avaliada antes de cada execução do corpo do loop.

A expressão for-initializer é avaliada antes da primeira avaliação da expressão de controle. A expressão for-initializer é avaliada apenas para seus efeitos colaterais; qualquer valor que ele produz é descartado e não é gravado no pipeline.

A expressão for-iterator é avaliada após cada execução do corpo do loop. A expressão for-iterator é avaliada apenas para seus efeitos colaterais; qualquer valor que ele produz é descartado e não é gravado no pipeline.

Se a expressão para condição for omitida, a expressão de controle testará 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 instrução foreach

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 do loop, que consiste em statement-block, é executado para cada elemento designado pela variável variable na coleção designada pelo pipeline. O escopo da variável não se limita à instrução foreach. Assim, ele retém seu valor final após a execução do corpo do loop. Se pipeline designa um escalar (excluindo o valor $null) em vez de uma coleção, esse escalar será tratado como uma coleção de um elemento. Se o pipeline designar o valor $null, o pipeline é tratado como uma coleção de nenhum elemento.

Se foreach-parameter-parallel for especificado, o comportamento será definido pela implementação.

O foreach-parameter‑parallel somente é permitido em um fluxo de trabalho (§8.10.2).

Cada instrução foreach tem seu próprio enumerador, $foreach (§2.3.2.2, §4.5.16), que existe somente enquanto esse loop está em execução.

Os objetos produzidos pelo pipeline são coletados antes que o statement-block comece a ser executado. No entanto, com o cmdlet forEach-Object, o bloco de instruções é executado em cada objeto conforme ele é 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 Instruções de controle de fluxo

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 instrução de controle de fluxo causa uma transferência incondicional de controle para algum outro local.

8.5.1 A instrução break

Descrição:

Uma instrução break com uma label-expression é conhecida como uma instrução break rotulada. Uma instrução break sem uma label-expression é conhecida como uma instrução break não rotulada.

Fora de uma instrução trap, uma instrução break sem rótulo diretamente dentro de uma instrução de iteração (§8.4) encerra a execução da menor instrução de iteração delimitada. Uma instrução break sem rótulo diretamente dentro de uma instrução switch (§8.6) encerra a correspondência de padrões para a switch-condition atual do switch. Confira (§8.8) para obter detalhes sobre como usar a quebra de dentro de uma instrução trap.

Uma instrução de iteração ou uma instrução switch pode, opcionalmente, ser precedida imediatamente por um rótulo de instrução (§8.1.1). Esse rótulo de instrução pode ser usado como o destino de uma instrução break rotulada, nesse caso, essa instrução encerra a execução da instrução de iteração de destino delimitada.

Uma quebra rotulada não precisa ser resolvida em nenhum escopo local; a pesquisa de um rótulo correspondente pode continuar a pilha de chamada mesmo entre limites de script e function-call. Se nenhum rótulo de correspondência for encontrado, a invocação de comando atual será encerrada.

O nome do rótulo designado por label-expression não precisa ter um valor constante.

Se label-expression for uma unary-expression, ela será convertida em uma cadeia de caracteres.

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 instrução continue

Descrição:

Uma instrução continue com uma label-expression é conhecida como uma instrução continue rotulada. Uma instrução continue sem uma label-expression é conhecida como uma instrução continue não rotulada.

O uso de continue dentro de uma instrução trap é discutido em §8.8.

Uma instrução continue sem rótulo dentro de um loop encerra a execução do loop atual e transfere o controle para a chave de fechamento da menor instrução de iteração delimitada (§8.4). Uma instrução continue sem rótulo dentro de um switch encerra a execução da iteração switch atual e transfere o controle para a menor switch-condition delimitada de switch (§8.6).

Uma instrução de iteração ou uma instrução switch (§8.6) pode, opcionalmente, ser precedida imediatamente por um rótulo de instrução (§8.1.1). Esse rótulo de instrução pode ser usado como o destino de uma instrução continue rotulada delimitada, nesse caso, essa instrução encerra a execução do loop ou iteração switch atual e transfere o controle para o rótulo de instrução switch ou iteração delimitada de destino.

Uma continue rotulada não precisa ser resolvida em nenhum escopo local; a pesquisa de um rótulo correspondente pode continue a pilha de chamada mesmo entre limites de script e function-call. Se nenhum rótulo de correspondência for encontrado, a invocação de comando atual será encerrada.

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

Se label-expression for uma unary-expression, ela será convertida em uma cadeia de caracteres.

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 instrução throw

Descrição:

Uma exceção é uma maneira de lidar com uma condição de erro no nível do sistema ou do aplicativo. A instrução throw gera uma exceção (Consulte §8.7 para uma discussão sobre tratamento de exceção.)

Se o pipeline for omitido e a instrução throw não estiver em uma catch-clause, o comportamento será definido pela implementação. Se o pipeline estiver presente e a instrução throw estiver em uma catch-clause, a exceção que foi capturada por essa catch-clause será lançada depois que qualquer finally-clause associada à catch-clause for executada.

Se o pipeline estiver presente, o tipo da exceção lançada será definido pela implementação.

Quando uma exceção é lançada, o controle é transferido para a primeira cláusula catch em uma instrução try delimitada que pode manipular a exceção. O local no qual a exceção é lançada inicialmente é chamado de ponto de lançamento. Depois que uma exceção é lançada, as etapas descritas em §8.7 são seguidas repetidamente até que uma cláusula catch que corresponde à exceção seja encontrada ou nenhuma possa ser encontrada.

Exemplos:

throw
throw 100
throw "No such record in file"

Se o pipeline for omitido e a instrução throw não estiver dentro de uma catch-clause, o texto "ScriptHalted" será gravado no pipeline e o tipo da exceção acionado será System.Management.Automation.RuntimeException.

Se o pipeline estiver presente, a exceção a ser criada será envolvida em um objeto do tipo System.Management.Automation.RuntimeException, que inclui informações sobre a exceção como um objeto System.Management.Automation.ErrorRecord (acessível por meio de $_).

Exemplo 1: throw 123 resulta em uma exceção do tipo RuntimeException. De dentro do bloco catch, $_.TargetObject contém o objeto envolvido dentro, nesse caso, um System.Int32 com valor 123.

Exemplo 2: throw "xxx" resulta em uma exceção do tipo RuntimeException. No bloco catch, $_.TargetObject contém o objeto encapsulado dentro, nesse caso, um System.String com o valor "xxx".

Exemplo 3: throw 10,20 resulta em uma exceção do tipo RuntimeException. De dentro do bloco catch, $_.TargetObject contém o objeto envolvido dentro, nesse caso, um System.Object[], uma matriz não restrita de dois elementos com os valores System.Int32` de 10 e 20.

8.5.4 A instrução return

Descrição:

A instrução return grava no pipeline os valores designados por pipeline, se houver, e retorna o controle para a função ou o chamador do script. Uma função ou script pode ter nenhuma ou mais instruções return.

Se a execução atingir a chave de fechamento de uma função, um return implícito sem pipeline será presumido.

A instrução return é um tipo de "açúcar sintático" para permitir que os programadores se expressem como podem em outras linguagens; no entanto, o valor retornado de uma função ou script é, na verdade, todos os valores gravados no pipeline por essa função ou script mais quaisquer valores especificados pelo pipeline. Se apenas um valor escalar for gravado no pipeline, seu tipo será o tipo do valor retornado; caso contrário, o tipo de retorno é uma matriz unidimensional não restrita que contém todos os valores gravados no pipeline.

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 para Get-Factorial obtém de volta 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 para Test obtém de volta uma matriz unidimensional não restrita de três elementos.

8.5.5 A instrução de saída

Descrição:

A instrução exit encerra o script atual e retorna o controle e um código de saída para o ambiente do host ou o script de chamada. Se o pipeline for fornecido, o valor designado será convertido em int, se necessário. Se nenhuma conversão desse tipo existir ou se pipeline for omitido, o valor de int zero será retornado.

Exemplos:

exit $count # terminate the script with some accumulated count

8.6 A instrução switch

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 switch-condition designar um único valor, o controle será passado para um ou mais blocos de instrução padrão correspondentes. Se nenhum padrão corresponder, alguma ação padrão poderá ser executada.

Uma opção deve conter uma ou mais switch-clauses, cada uma começando com um padrão (uma cláusula switch não padrão) ou a palavra-chave default (uma cláusula switch padrão). Uma opção deve conter nenhuma ou uma cláusula switch default e nenhuma ou mais cláusulas de opção não padrão. As cláusulas switch podem ser escritas em qualquer ordem.

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

Se o valor da condição do switch corresponder a um valor padrão, o bloco de instruções desse padrão será executado. Se vários valores de padrão correspondem ao valor de switch-condition, cada statement-block do padrão correspondente será executado, em ordem lexical, a menos que qualquer um dos statement-blocks contenha uma instrução break (§8.5.1).

Se o valor de switch-condition não corresponder a nenhum valor de padrão, se existir uma cláusula switch default, seu statement-block será executado; caso contrário, a correspondência de padrões para essa switch-condition será encerrada.

As opções podem ser aninhadas, com cada opção tendo seu próprio conjunto de cláusulas switch. Nesses casos, uma cláusula switch pertence à opção mais interna atualmente no escopo.

Na entrada para cada statement-block, $_ é atribuído automaticamente o valor de switch-condition que fez o controle ir para esse statement-block. $_ também está disponível em switch-clause-condition do statement-block.

A correspondência de não cadeias de caracteres é feita testando a igualdade (§7.8.1).

Se a correspondência envolver cadeias de caracteres, por padrão, a comparação não faz distinção de maiúsculas e minúsculas. A presença de switch-parameter-casesensitive indica que a comparação faz distinção de maiúsculas e minúsculas.

Um padrão pode conter caracteres curinga (§3.15); neste caso, são realizadas comparações de cadeias de caracteres curinga, mas somente se o parâmetro de alternância -wildcard estiver presente. Por padrão, a comparação não diferencia maiúsculas de minúsculas.

Um padrão pode conter uma expressão regular (§3.16), nesse caso, comparações de cadeia de caracteres de expressão regular são executadas, mas somente se switch-parameter-regex estiver presente. Por padrão, a comparação não diferencia maiúsculas de minúsculas. Se -regex estiver presente e um padrão corresponder, $matches será definido no switch-clausestatement-block para esse padrão.

Um switch-parameter pode ser abreviado; qualquer parte principal distinta de um parâmetro pode ser usada. Por exemplo, ‑regex, ‑rege, ‑reg, ‑ree ‑r são equivalentes.

Se os switch-parameters conflitantes forem especificados, o léxico final prevalecerá. A presença de ‑exact desabilita -regex e -wildcard; no entanto, não afeta ‑case.

Se switch-parameter‑parallel for especificado, o comportamento será definido pela implementação.

O switch-parameter‑parallel somente é permitido em um fluxo de trabalho (§8.10.2).

Se um padrão for uma script-block-expression, esse bloco será avaliado e o resultado será convertido em bool, se necessário. Se o resultado tiver o valor $true, o bloco de instrução correspondente,, será executado; caso contrário, não será.

Se a condição de alternância designar vários valores, a alternância será aplicada a cada valor em ordem lexical usando as regras descritas acima para uma condição de alternância que designa um único valor. Cada instrução switch tem seu próprio enumerador, $switch (§2.3.2.2, §4.5.16), que existe somente enquanto essa instrução switch está em execução.

Uma instrução switch pode ter um rótulo e pode conter instruções de quebra rotuladas e sem rótulo (§8.5.1) e instruções continue (§8.5.2).

Se switch-condition for -fileswitch-filename, em vez de iterar sobre os valores em uma expressão, o switch itera sobre os valores no arquivo designado por switch-filename. O arquivo é lido uma linha por vez com cada linha que inclui um valor. Os caracteres do terminador 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 instrução try/finally

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 instrução try fornece um mecanismo para capturar exceções que ocorrem durante a execução de um bloco. A instrução try também fornece a capacidade de especificar um bloco de código que sempre é executado quando o controle deixa a instrução try. O processo de gerar uma exceção por meio da instrução throw é descrito em §8.5.3.

Um bloco try é o statement-block associado à instrução try. Um bloco catch é o statement-block associado a uma catch-clause. Um bloco finally é o statement-block associado a uma finally-clause.

Uma catch-clause uma catch-type-list é chamada de cláusula catch geral.

Cada catch-clause é um manipulador de exceção, e uma catch-clause cujo catch-type-list contém o tipo da exceção gerada é uma cláusula catch correspondente. Uma cláusula catch geral corresponde a todos os tipos de exceção.

Embora catch-clauses e finally-clause sejam opcionais, pelo menos uma delas deve estar presente.

O processamento de uma exceção lançada consiste em avaliar as etapas a seguir repetidamente até que uma cláusula catch que corresponde à exceção seja encontrada.

  • No escopo atual, cada instrução try que inclui o ponto de lançamento é examinada. Para cada instrução try S, começando com a instrução try mais interna e terminando com a instrução try mais externa, as seguintes etapas são avaliadas:

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

    • Caso contrário, se o bloco try ou um bloco catch de S incluir o ponto de lançamento e se S tiver um bloco finally, o controle será transferido para o bloco finally. Se o bloco finally gerar outra exceção, o processamento da exceção atual será encerrado. Caso contrário, quando o controle atingir o final do bloco finally, o processamento da exceção atual será continuado.

  • Se um manipulador de exceção não estiver localizado no escopo atual, as etapas acima serão repetidas para o escopo delimitador com um ponto de lançamento correspondente à instrução da qual o escopo atual foi invocado.

  • Se o processamento de exceção acabar encerrando todos os escopos, indicando que nenhum manipulador existe para a exceção, o comportamento não será especificado.

Para evitar cláusulas catch inacessíveis em um bloco try, uma cláusula catch pode não especificar um tipo de exceção que seja igual a ou derivado de um tipo especificado em uma cláusula catch anterior dentro desse mesmo bloco try.

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

Se uma exceção for lançada durante a execução de um bloco finally, a exceção será lançada para a próxima instrução try delimitada. Se outra exceção estiver no processo de tratamento, essa exceção será perdida. O processo de geração de uma exceção é discutido ainda mais na descrição da instrução throw.

Instruções try podem coexistir com instruções trap; consulte §8.8 para obter 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 é acionada como um System.Management.Automation.RuntimeException. Se houver catch-clauses específicas do tipo no bloco try, a propriedade InnerException da exceção será inspecionada para tentar encontrar uma combinação, como com o tipo System.IndexOutOfRangeException acima.

8.8 A instrução trap

Sintaxe:

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

Descrição:

Uma instrução trap com e sem type-literal é análoga a um bloco catch (§8.7) com e sem catch-type-list, respectivamente, exceto que uma instrução trap pode interceptar apenas um tipo por vez.

Várias instruções trap podem ser definidas no mesmo bloco de instruções , e sua ordem de definição é irrelevante. Se duas instruções trap com o mesmo type-literal são definidas no mesmo escopo, a primeira lexicalmente é usada para processar uma exceção do tipo correspondente.

Ao contrário de um bloco catch, uma instrução trap corresponde exatamente a um tipo de exceção; nenhuma correspondência de tipo derivada é executada.

Quando ocorre uma exceção, se nenhuma instrução trap correspondente estiver presente no escopo atual, uma instrução de interceptação correspondente será pesquisada no escopo delimitador, o que pode envolver a pesquisa no script de chamada, função ou filtro e, em seguida, em seu chamador e assim por diante. Se a pesquisa acabar encerrando todos os escopos, indicando que não existe nenhum tratador para a exceção, o comportamento será indefinido.

Um statement-body da instrução trap é executado apenas para processar a exceção correspondente; caso contrário, a execução é passada por ela.

Se o statement-body de um trap sair normalmente, por padrão, um objeto de erro será gravado no fluxo de erro, a exceção será considerada tratada e a execução continuará com a instrução imediatamente após aquela no escopo que contém a instrução trap que tornou a exceção visível. A causa da exceção pode estar em um comando chamado pelo comando que contém a instrução trap.

Se a instrução final executada no statement-body de um trap for continue (§8.5.2), a escrita do objeto de erro no fluxo de erro será suprimida e a execução continuará com a instrução imediatamente após aquela no escopo que contém a instrução trap que tornou a exceção visível. Se a instrução final executada no statement-body de um trap for break (§8.5.1), a escrita do objeto de erro no fluxo de erro será suprimida e a exceção será lançada de novo.

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

Considere o caso em que uma exceção gerada a partir de um bloco try não tem um bloco catch correspondente, mas existe uma instrução trap correspondente em um nível de bloco mais alto. Depois que a cláusula finally do bloco try é executada, a instrução trap obtém o controle mesmo que qualquer escopo pai tenha um bloco catch correspondente. Se uma instrução trap for definida dentro do próprio bloco try e esse bloco try tiver um bloco de catch correspondente, a instrução trap obterá o controle.

Exemplos:

No exemplo a seguir, o objeto de erro é gravado e a execução continua com a instrução imediatamente após aquela que causou a interceptação; ou seja, "Done" é gravado no pipeline.

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

No exemplo a seguir, a gravação do objeto de erro é suprimida e a execução continua com a instrução imediatamente após aquela que causou a interceptação; ou seja, "Done" é gravado no pipeline.

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

No exemplo a seguir, a gravação do objeto de erro é suprimida e a exceção é lançada.

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

No exemplo a seguir, as instruções trap e exception-generating estão no mesmo escopo. Depois que a exceção é capturada e tratada, a execução é retomada com a gravação 1 no pipeline.

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

No exemplo a seguir, as instruções trap e exception-generating estão em escopos diferentes. Depois que a exceção é capturada e tratada, a execução é retomada com a gravação 2 (não 1) no pipeline.

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

8.9 A instrução data

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 instrução de dados cria uma seção de dados , mantendo os dados dessa seção separados do código. Essa separação oferece suporte a funcionalidades como arquivos de recursos de cadeia de caracteres independentes para texto, como mensagens de erro e cadeias de caracteres de ajuda. Ele também ajuda a dar suporte à internacionalização, facilitando o isolamento, a localização e o processo de cadeias de caracteres que serão convertidas em idiomas diferentes.

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

O bloco de instrução da seção de dados está limitado a conter somente os seguintes recursos do PowerShell:

  • Todos os operadores, exceto -match
  • A instrução if
  • As seguintes variáveis automáticas: $PsCulture, $PsUICulture, $true, $falsee $null.
  • Comentários
  • Linhas de Produção
  • Declarações separadas por ponto-e-vírgula (;)
  • Literais
  • Chamadas para o cmdlet ConvertFrom-StringData
  • Quaisquer outros cmdlets identificados por meio do parâmetro supportedcommand

Se o cmdlet ConvertFrom-StringData for usado, os pares chave/valor podem ser expressos usando qualquer forma de string literal. No entanto, expandable-string-literals e expandable-here-string-literals não devem conter nenhuma substituição de variável ou expansões de subexpressão.

Exemplos:

O parâmetro SupportedCommand indica que os cmdlets ou funções determinados geram somente dados. Por exemplo, a seção de dados a seguir inclui um cmdlet escrito pelo usuário, ConvertTo-XML, que formata dados em um arquivo XML:

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

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

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

As chaves e os valores da tabela de hash são acessados usando $messages.Greeting, $messages.Yese $messages.No, respectivamente.

Agora, isso pode ser salvo como um recurso em inglês. Os recursos em alemão e espanhol podem ser criados em arquivos separados, com as seguintes seçõ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 dataname estiver presente, ele nomeará a variável (sem usar um $ no início) na qual o valor da instrução de dados 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á sendo definido e os nomes de seus parâmetros, se houver. Ele também contém nenhuma ou mais instruções que são executadas para atingir a finalidade dessa função.

Cada função é uma instância da classe System.Management.Automation.FunctionInfo.

8.10.1 Funções de filtro

Enquanto uma função comum é executada uma vez em um pipeline e acessa a coleção de entrada por meio de $input, um filtro é um tipo especial de função que é executada uma vez para cada objeto na coleção de entrada. O objeto que está sendo processado está disponível por meio 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 é uma instância 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 pela implementação. Uma função de fluxo de trabalho é traduzida para uma sequência de atividades do Windows Workflow Foundation e executada no mecanismo do 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
}

Essa função tem dois parâmetros, $base e $exponent. Ele também contém um conjunto de instruções que, para valores de expoentes não negativos, calcula $base^$exponent^ e retorna o resultado ao chamador de Get-Power.

Quando um script, uma função ou um filtro inicia a execução, cada parâmetro é inicializado para o valor do argumento correspondente. Se não houver nenhum argumento correspondente e um valor padrão (§8.10.4) for fornecido, esse valor será usado; caso contrário, o valor $null é usado. Dessa forma, cada parâmetro é uma nova variável exatamente como se tivesse sido inicializada por atribuição no início do bloco de script .

Se um script-parâmetro contiver uma restrição de tipo (como [long] e [int] acima), o valor do argumento correspondente será convertido nesse tipo, se necessário; caso contrário, nenhuma conversão ocorrerá.

Quando um script, uma função ou um filtro inicia a execução, a variável $args é definida dentro dela como uma matriz unidimensional não restrita, que contém todos os argumentos não associados por 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 associação de parâmetros, consulte §8.14.

8.10.4 Inicializadores de parâmetro

A declaração de um parâmetro p pode conter um inicializador. Caso contrário, o valor desse inicializador é usado para inicializar p, desde que p não esteja vinculado a nenhum argumento 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 comutador é passado, o parâmetro correspondente no comando deve ser restringido pelo comutador de tipo. O tipo switch tem dois valores, True e False.

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

Quando um script, função ou filtro é usado em um pipeline, uma coleção de valores é entregue a esse script ou função. O script, a função ou o filtro obtém acesso a essa coleção por meio do enumerador $input (§2.3.2.2, §4.5.16), que é definido na entrada desse 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 instruções em um bloco de script podem pertencer a um grande bloco sem nome ou podem ser organizadas em um ou mais blocos nomeados. Os blocos nomeados permitem o processamento personalizado de coleções provenientes de pipelines; os blocos nomeados podem ser definidos em qualquer ordem.

As instruções em um bloco begin (ou seja, uma marcada com a palavra-chave begin) são executadas uma vez, antes que o primeiro objeto de pipeline seja entregue.

As instruções em um bloco process (ou seja, uma marcada com a palavra-chave process) são executadas para cada objeto de pipeline entregue. ($_ fornece acesso ao objeto atual que está sendo processado da coleção de entrada proveniente do pipeline.) Isso significa que, se uma coleção de elementos zero for enviada por meio do pipeline, o bloco de processo não será executado. No entanto, se o script ou a função for chamado fora de um contexto de pipeline, esse bloco será executado exatamente uma vez e $_ será definido como $null, pois não há nenhum objeto de coleção atual.

As instruções em um bloco end (ou seja, uma marcada com a palavra-chave end) são executadas uma vez, após o último objeto de pipeline ter sido entregue.

8.10.8 Bloco dynamicparam

As subseções de §8.10 até agora lidam com parâmetros estáticos, que são definidos como parte do código-fonte. Também é possível definir parâmetros dinâmicos por meio de um bloco dynamicparam, outra forma de bloco nomeado (§8.10.7), que é marcada com a palavra-chave dynamicparam. Grande parte desse maquinário é definida pela implementação.

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 cmdlet Set-Item.

No bloco de instrução , use uma instrução if para especificar as condições sob as quais o parâmetro está disponível na função. Use o cmdlet New-Object para criar um objeto de um tipo definido pela implementação para representar o parâmetro e especificar seu nome. Além disso, use New-Object para criar um objeto de um tipo definido por implementação diferente para representar os atributos definidos pela implementação do parâmetro.

O exemplo a seguir mostra uma função com parâmetros padrão chamados 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 está disponível na função de amostra somente quando o valor do parâmetro de caminho contém "HKLM:", indicando que ele está sendo usado na unidade do registro HKEY_LOCAL_MACHINE.

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 usado para criar um objeto para representar os atributos do parâmetro é System.Management.Automation.ParameterAttribute.

Os atributos definidos pela implementação do parâmetro incluemObrigatório , Posiçãoe ValueFromPipeline.

Bloco de parâmetros 8.10.9

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

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

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

Um script pode ter um bloco de parâmetros , 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âmetros de função ou um bloco de parâmetros , mas não ambos ao mesmo tempo.

Considere o seguinte exemplo:

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

O parâmetro $ComputerName tem tipo string[], é obrigatório e recebe dados do pipeline.

Confira §12.3.7 para obter uma discussão sobre o atributo Parameter e obter mais exemplos.

8.11 A instrução parallel

Sintaxe:

parallel-statement:
    *parallel* statement-block

A instrução paralela contém zero ou mais instruções executadas de maneira definida pela implementação.

Uma instrução paralela só é permitida em um fluxo de trabalho (§8.10.2).

8.12 A instrução sequence

Sintaxe:

sequence-statement:
    *sequence* statement-block

A instrução de sequência contém zero ou mais instruções executadas de maneira definida pela implementação.

Uma instrução de sequência só é permitida em um fluxo de trabalho (§8.10.2).

8.13 A instrução inlinescript

Sintaxe:

inlinescript-statement:
    inlinescript statement-block

A instrução inlinescript contém nenhuma ou mais instruções que são executadas em uma maneira definida pela implementação.

Uma instrução de script embutido só é permitida em um fluxo de trabalho (§8.10.2).

8.14 Associação de parâmetro

Quando um script, função, filtro ou cmdlet é invocado, cada argumento pode ser associado ao parâmetro correspondente por posição, com o primeiro parâmetro tendo a posição zero.

Considere o seguinte fragmento de definição para uma função chamada Get-Powere as chamadas a ela:

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 é invocado, um argumento pode ser associado ao parâmetro correspondente pelo nome. Isso é feito usando um parâmetro com o argumento, que é o nome do parâmetro precedido por um traço (-), seguido do valor associado a esse argumento. O nome do parâmetro usado pode ter qualquer ortografia que não diferencia maiúsculas de minúsculas e pode usar qualquer prefixo que designe exclusivamente o parâmetro correspondente. Ao escolher nomes de parâmetro, evite usar os nomes dos parâmetros comuns .

Considere as seguintes chamadas para a função 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, as chamadas para função a seguir

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

deve usar parâmetros -side1 e -side2, pois não há 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 seções em §12.3. Para obter informações sobre conjuntos de parâmetros, consulte §12.3.7.

Um script, uma função, um filtro ou um cmdlet podem receber argumentos por meio da linha de comando de invocação, do pipeline ou de ambos. Estas são as etapas, em ordem, para resolver a associação de parâmetros:

  1. Associar todos os parâmetros nomeados e, em seguida
  2. Associar parâmetros posicionais e, em seguida,
  3. Associar do pipeline por valor (§12.3.7) com correspondência exata e, em seguida
  4. Associar do pipeline por valor (§12.3.7) com a conversão e, em seguida
  5. Associar do pipeline por nome (§12.3.7) com correspondência exata e, em seguida
  6. Associar do pipeline por nome (§12.3.7) com a conversão

Várias dessas etapas envolvem conversão, conforme descrito em §6. No entanto, o conjunto de conversões usadas na associação não é exatamente o mesmo usado em conversões de idioma. Especificamente

  • Embora o valor $null possa ser convertido em bool, $null não pode ser associado a bool.
  • Quando o valor $null é passado para um parâmetro switch de um cmdlet, ele é tratado como se $true fosse passado. No entanto, quando passado para um parâmetro switch para uma função, ele é tratado como se $false tivesse sido passado.
  • Parâmetros de tipo bool ou switch só podem ser associados 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 coleção, nenhuma conversão será tentada, a menos que o tipo de parâmetro seja objeto ou PsObject. (O ponto principal dessa restrição é não permitir a conversão de uma coleção em um parâmetro de cadeia de caracteres.) Caso contrário, as conversões usuais serão tentadas.

Se o tipo de parâmetro for IList ou ICollection<T>, somente essas conversões por meio de Construtor, op_Implicit e op_Explicit serão tentadas. Se essas conversões não existirem, será usada uma conversão especial para parâmetros do tipo "collection", que inclui IList, ICollection<T>e matrizes.

Os parâmetros posicionais preferem ser associados sem conversão de 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"