Поделиться через


8. Инструкции

Редакционная заметка

Это важно

Спецификация языка Windows PowerShell 3.0 была опубликована в декабре 2012 года и основана на Windows PowerShell версии 3.0. Эта спецификация не отражает текущее состояние PowerShell. Нет плана обновить эту документацию, чтобы отразить текущее состояние. Эта документация представлена здесь для получения исторической справки.

Документ спецификации доступен в формате Microsoft Word из Центра загрузки Майкрософт: https://www.microsoft.com/download/details.aspx?id=36389. Этот документ был преобразован и представлен здесь на Microsoft Learn. Во время преобразования некоторые редакционные изменения были внесены в соответствии с форматированием платформы Docs. Исправлены некоторые опечатки и незначительные ошибки.

8.1. Блоки и списки инструкций

Синтаксис:

Подсказка

Нотация ~opt~ в определениях синтаксиса указывает, что лексическая сущность является необязательной в синтаксисе.

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

Описание:

Оператор указывает какой-то вид действия, который требуется выполнить. Если в этом предложении не указано иное, операторы выполняются в лексическом порядке.

Блок инструкций позволяет сгруппировать набор инструкций в одну синтаксическую единицу.

Операторы с метками 8.1.1

Синтаксис:

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

Описание:

Оператор итерации (§8.4) или оператор switch (§8.6) может быть при необходимости предшествует одной меткой оператора, меткой. Метка оператора используется как необязательный целевой объект разрыва (§8.5.1) или продолжить (§8.5.2). Однако метка не изменяет поток управления.

Пробелы не допускаются между двоеточием (:) и маркером, который следует за ним.

Примеры.

: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

Значение инструкции — это совокупный набор значений, которые он записывает в конвейер. Если оператор записывает одно скалярное значение, то это значение инструкции. Если инструкция записывает несколько значений, то значение инструкции — это набор значений, хранящихся в элементах неограниченного 1-мерного массива, в том порядке, в котором они были записаны. Рассмотрим следующий пример:

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

Цикл не выполняет итерации, и ничего не записывается в конвейер. Значение инструкции — $null.

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

Хотя цикл итерирует пять раз ничего не записывается в конвейер. Значение инструкции — $null.

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

Цикл выполняет итерацию пять раз при записи в конвейер int значения $i. Значение инструкции — object[] Длина 5.

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

Хотя цикл итерирует пять раз ничего не записывается в конвейер. Значение инструкции — $null.

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

Цикл выполняет итерацию пять раз с каждым значением, записанным в конвейер. Значение инструкции — object[] Длина 5.

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

Цикл выполняет итерацию один раз. Значение инструкции — значение int 2.

Ниже приведены другие примеры.

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

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

        "odd"            # conditionally written to the pipeline

    }

    ++$i                 # not written to the pipeline

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

Операторы конвейера 8.2

Синтаксис:

pipeline:
    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

Описание:

перенаправления обсуждаются в §7.12; выражение назначения рассматривается в §7.11; и точка вызова команды (.) рассматривается в §3.5.5. Обсуждение сопоставления аргументов и параметров в вызовах команд см. в разделе "8.14".

Первая команда в конвейере — это выражение или вызов команды. Как правило, вызов команды начинается с имени команды, который обычно является идентификатором без использования. Командные элементы представляют список аргументов для команды. Новая строка или n неискаченная точка с запятой завершает конвейер.

Вызов команды состоит из имени команды, за которой следует нулевая или более аргументов. Ниже приведены правила, управляющие аргументами.

  • Аргумент, который не является выражением, но который содержит произвольный текст без неискаченного пробела, рассматривается как будто он был двойным кавычки. Регистр букв сохраняется.

  • Подстановка переменных и расширение вложенных выражений (§2.3.5.2) происходит внутри расширяемых строковых литеральныхs и расширяемых строковых литеральныхs.

  • Текст внутри кавычки позволяет включать в значение аргумента начальные, конечные и внедренные пробелы. [Примечание. Наличие пробелов в кавычки аргумента не превращает один аргумент в несколько аргументов. конечная заметка]

  • Размещение круглых скобок вокруг аргумента приводит к оценке выражения с результатом, передаваемым вместо текста исходного выражения.

  • Чтобы передать аргумент, который выглядит как параметр switch (§2.3.4), но не предназначен таким образом, заключите этот аргумент в кавычки.

  • При указании аргумента, совпадающего с параметром с [switch] ограничением типа (§8.10.5), наличие имени аргумента в собственных случаях приводит к тому, что этот параметр должен быть задан $true. Однако значение параметра можно задать явно, добавив к аргументу суффикс. Например, если задан параметр ограниченного типа p, аргумент -p:$true набора p в true, а -p:$false для параметра p — false.

  • Аргумент -- указывает, что все аргументы, следующие за ним, должны быть переданы в их фактической форме, как будто двойные кавычки были помещены вокруг них.

  • Аргумент --% указывает, что все аргументы, следующие за ним, должны передаваться с минимальным анализом и обработкой. Этот аргумент называется параметром verbatim. Аргументы после параметра verbatim не являются выражениями PowerShell, даже если они являются синтаксически допустимыми выражениями PowerShell.

Если тип команды — Application, параметр --% не передается команде. Аргументы после --% расширения любых переменных среды (строки, окруженные %) Рассмотрим пример.

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

Порядок оценки аргументов не определен.

Сведения о привязке параметров см. в §8.14. Сведения о поиске имен см. в разделе §3.8.

После завершения обработки аргументов вызывается команда. Если вызываемая команда завершается нормально (§8.5.4), элемент управления возвращается к точке сценария или функции сразу после вызова команды. Описание поведения при ненормальном завершении см. в разделе break (§8.5.1), continue (§8.5.2), throw (§8.5.3), (§8.5.5), tryexit8.7) и trap8.8).

Обычно команда вызывается с помощью имени, за которым следует все аргументы. Однако можно использовать оператор вызова команд >. Если имя команды содержит незаключенные пробелы, его необходимо кавычекировать и вызвать с помощью этого оператора. Как блок скрипта не имеет имени, он также должен вызываться с помощью этого оператора. Например, следующие вызовы команды Get-Factorial эквивалентны:

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

Разрешены прямые и косвенные рекурсивные вызовы функций. Например

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

Примеры.

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

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

dir E:\PowerShell\Scripts\*.ps1 |
    Select-String -List "catch" |
    Format-Table Path, LineNumber -AutoSize

8.3 Оператор if

Синтаксис:

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

Описание:

Выражения, управляющие конвейером , должны иметь логический тип или неявно преобразуемый в этот тип. Предложение else-необязательный . Может быть нулевое или более предложение elseif-.

Если конвейер верхнего уровня проверяет значение True, выполняется его блок инструкции , а выполнение инструкции завершается. В противном случае, если присутствует предложение elseif-, если выполняется проверка конвейера True, выполняется его блок инструкции и завершается выполнение инструкции. В противном случае, если присутствует предложение else,егоблок инструкции выполняется.

Примеры.

$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

8.4.1 Оператор while

Синтаксис:

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

while-condition:
    new-lines~opt~ pipeline

Описание:

Управляемое выражение в то время как условие должно иметь тип bool или быть неявно преобразованным в этот тип. Текст цикла, состоящий из блока инструкций, выполняется многократно, пока контрольное выражение не проверяет false. Управляющее выражение вычисляется перед каждым выполнением текста цикла.

Примеры.

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

8.4.2 Инструкция do

Синтаксис:

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

Описание:

Управляемое выражение в то время как условие должно иметь тип bool или быть неявно преобразованным в этот тип. В форме, текст цикла, состоящий из блока инструкций, выполняется многократно, пока контрольное выражение проверяет значение True. В форме до тех пор текст цикла выполняется многократно, пока контрольное выражение не проверяет значение True. Управляемое выражение вычисляется после каждого выполнения текста цикла.

Примеры.

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

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

8.4.3 Инструкция for

Синтаксис:

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

Описание:

Управляемое выражение для условия должно иметь тип bool или быть неявно преобразованным в этот тип. Текст цикла, состоящий из блока инструкций, выполняется многократно при проверке управляемого выражения true. Управляющее выражение вычисляется перед каждым выполнением текста цикла.

Выражение для инициализатора вычисляется перед первой оценкой управляемого выражения. Выражение для инициализатора оценивается только для побочных эффектов; любое значение, которое он создает, удаляется и не записывается в конвейер.

Выражение для итератора вычисляется после каждого выполнения текста цикла. Выражение для итератора оценивается только для побочных эффектов; любое значение, которое он создает, удаляется и не записывается в конвейер.

Если выражение для условия опущено, контрольное выражение проверяет значение True.

Примеры.

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

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

8.4.4 Оператор foreach

Синтаксис:

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

Описание:

Текст цикла, состоящий из блока инструкций, выполняется для каждого элемента, указанного переменной переменной в коллекции, указанной конвейером. Область переменной не ограничивается оператором foreach. Таким образом, он сохраняет окончательное значение после завершения выполнения текста цикла. Если конвейер назначает скалярную (за исключением значения $null) вместо коллекции, то скаляр рассматривается как коллекция одного элемента. Если конвейер обозначает значение $null, конвейер обрабатывается как коллекция нулевого элемента.

Если задан параметр -parallelforeach, то определяется поведение.

Параметр ‑parallelforeach разрешен только в рабочем процессе (§8.10.2).

Каждый оператор foreach имеет собственный перечислитель $foreach (§2.3.2.2, §4.5.16), который существует только во время выполнения этого цикла.

Объекты, созданные конвейером , собираются до начала выполнения блока инструкций . Однако при использовании командлета ForEach-Objectблок инструкции выполняется для каждого объекта по мере его создания.

Примеры.

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

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

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

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

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

Инструкции управления потоками 8.5

Синтаксис:

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

Описание:

Оператор управления потоком вызывает безусловную передачу управления в другое расположение.

8.5.1 Оператор останова

Описание:

Оператор останова с выражением метки называется меткой оператором останова. Оператор останова без выражения метки называется оператором без метки.

Вне оператора ловушки оператор без метки оператор останова непосредственно в операторе итерации (§8.4) завершает выполнение этого наименьшего заключителя инструкции итерации. Оператор разбиения без метки непосредственно в операторе switch (§8.6) завершает сопоставление шаблонов для условия коммутатора текущего коммутатора. Дополнительные сведения об использовании перерыва в операторе ловушки см. в разделе (§8.8).

Оператор итерации или оператор switch могут быть при необходимости предшествовать одной метки инструкции (§8.1.1). Такая метка инструкции может использоваться в качестве целевого объекта инструкции разбиения с метками, в этом случае инструкция завершает выполнение целевой инструкции итерации.

Не нужно разрешать помеченный разрыв в какой-либо локальной области; Поиск соответствующей метки может продолжаться в стеке вызовов даже в пределах скрипта и вызовов функций. Если метка сопоставления не найдена, вызов текущей команды завершается.

Имя метки, указанной выражением метки , не требует постоянного значения.

Если выражение метки является унарным выражением, оно преобразуется в строку.

Примеры.

$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 Инструкция continue

Описание:

Оператор continue с выражением метки называется оператором continue с меткой. Оператор continue без выражения метки называется оператором unlabeled continue.

Использование из инструкции ловушки continue рассматривается в §8.8.

Оператор без метки continue в цикле завершает выполнение текущего цикла и передает управление закрывающей скобкой наименьшего заключающего оператора итерации (§8.4). Оператор без метки continue в коммутаторе завершает выполнение текущей switch итерации и передает управление наименьшему switchусловию переключателя (§8.6).

Оператор итерации или switch оператор (§8.6) может предшествовать немедленно одной меткой оператора (§8.1.1). Такая метка инструкции может использоваться в качестве целевого объекта заключенной помеченной continue инструкции, в этом случае инструкция завершает выполнение текущего цикла или switch итерации, а также передает управление целевой итерации, включающей итерацию или switch метку инструкции.

continue Метка не требуется разрешать в какой-либо локальной области. Поиск соответствующей метки может continue даже в разных границах скрипта и вызова функции. Если метка сопоставления не найдена, вызов текущей команды завершается.

Имя метки, указанной выражением метки , не требует постоянного значения.

Если выражение метки является унарным выражением, оно преобразуется в строку.

Примеры.

$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 Оператор throw

Описание:

Исключение — это способ обработки состояния ошибки на уровне системы или приложения. Оператор throw вызывает исключение. (См. статью 8.7 для обсуждения обработки исключений.)

Если конвейер опущен, а оператор throw не находится в предложении catch-, то поведение определяется. Если конвейер присутствует, а оператор throw находится в предложении catch-, исключение, которое было поймано этим предложением catch- создается повторно после выполнения любого предложения , связанного с предложением catch - .

Если конвейер присутствует, тип создаваемого исключения определяется реализацией.

При возникновении исключения элемент управления передается первому предложению catch в заключенном операторе try, который может обрабатывать исключение. Расположение, в котором создается исключение, изначально называется точкой вызова. После создания исключения шаги, описанные в §8.7 , повторяются повторно, пока не будет найдено предложение catch, соответствующее исключению, или нет.

Примеры.

throw
throw 100
throw "No such record in file"

Если конвейер опущен, а оператор создания не входит в предложение catch, текст ScriptHalted записывается в конвейер, а тип возникающего исключения .System.Management.Automation.RuntimeException

Если конвейер присутствует, возникающее исключение упаковывается в объект типа System.Management.Automation.RuntimeException, который включает сведения об исключении в виде System.Management.Automation.ErrorRecord объекта (доступно через $_).

Пример 1: throw 123 приводит к исключению типа RuntimeException. В блоке catch содержит объект, $_.TargetObject завернутый внутри, в данном случае значение System.Int32 123.

Пример 2: throw "xxx" приводит к исключению типа RuntimeException. В блоке catch содержит объект, $_.TargetObject завернутый внутри, в данном случае значение System.String "xxx".

Пример 3. throw 10,20 Приводит к исключению типа RuntimeException. В блоке catch содержит объект, $_.TargetObject завернутый внутри, в данном случае , System.Object[]неограниченный массив двух элементов с Systemобъектом. Значения Int32 10 и 20.

8.5.4 Инструкция return

Описание:

Оператор return записывает в конвейер значения, назначенные конвейером, если таковые имеются, и возвращает управление вызывающей функции или скрипта. Функция или скрипт могут иметь ноль или более return инструкций.

Если выполнение достигает закрывающей скобки функции, подразумеваемой return без конвейера , предполагается.

Оператор представляет собой немного "синтаксического сахара", чтобы программисты могли выразить себя так, как они могут на других языках. Однако return значение, возвращаемое функцией или скриптом, на самом деле является все значения, записанные в конвейер этой функцией или скриптом, а также любые значения, указанные конвейером. Если в конвейер записывается только скалярное значение, его тип является типом возвращаемого значения; В противном случае возвращаемый тип представляет собой неумерный массив, содержащий все значения, записанные в конвейер.

Примеры.

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

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

Вызывающий объект, возвращающий Get-Factorial объект 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
}

Вызывающий объект, возвращающий Test неограниченный 1-мерный массив трех элементов.

8.5.5 Инструкция выхода

Описание:

Оператор выхода завершает текущий скрипт и возвращает элемент управления и код выхода в среду узла или вызывающий скрипт. Если конвейер указан, значение, которое оно назначает, преобразуется в int при необходимости. Если такое преобразование не существует, или если конвейер опущен, возвращается нулевое значение int.

Примеры.

exit $count # terminate the script with some accumulated count

8.6 Оператор switch

Синтаксис:

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

Описание:

Если условие коммутатора обозначает одно значение, элемент управления передается одному или нескольким блокам инструкций шаблона. Если шаблонов не совпадает, можно выполнить некоторые действия по умолчанию.

Параметр должен содержать одно или несколько предложений switch-предложения, каждое из которых начинается с шаблона (предложение переключателя, отличное от по умолчанию), или ключевое слово default ( предложение switch по умолчанию). Параметр должен содержать ноль или одно default предложение коммутатора, а также ноль или несколько предложений, отличных от значений по умолчанию. Предложения switch могут быть записаны в любом порядке.

Несколько шаблонов могут иметь одно и то же значение. Шаблон не должен быть литералом, а параметр может иметь шаблоны с различными типами.

Если значение параметра-условия соответствует значению шаблона, выполняется блок инструкции этого шаблона. Если несколько значений шаблонов соответствуют значению параметра-условия, каждый соответствующий блок инструкции шаблона выполняется в лексическом порядке, если ни один из этих блоковинструкций не содержит break инструкцию (§8.5.1).

Если значение параметра-условия не соответствует ни одному значению шаблона, если default предложение switch существует, выполняется его блок инструкции ; в противном случае завершается сопоставление шаблонов для этого условия коммутатора .

Коммутаторы могут быть вложенными, при этом каждый коммутатор имеет собственный набор предложений коммутаторов. В таких случаях предложение switch принадлежит самому внутреннему коммутатору в настоящее время в области.

При записи к каждому блоку$_ инструкций автоматически назначается значение условия коммутатора, которое привело к переходу к данному блоку инструкций. $_также доступен в условии switch-clause-block этого оператора.

Сопоставление нестроковых элементов выполняется путем тестирования на равенство (§7.8.1).

Если сопоставление включает строки, по умолчанию сравнение не учитывает регистр. Наличие параметра switch-параметр-CaseSensitive учитывает регистр сравнения.

Шаблон может содержать подстановочные знаки (§3.15), в этом случае выполняется сравнение строк подстановочных знаков, но только в том случае, если параметр switch-Wildcard присутствует. По умолчанию сравнение не учитывает регистр.

Шаблон может содержать регулярное выражение (§3.16), в этом случае выполняются сравнения строк регулярных выражений, но только в том случае, если параметр switch присутствует-Regex . По умолчанию сравнение не учитывает регистр. Если -Regex присутствует и шаблон совпадает, $Matches определяется в блоке инструкции switch-clause для этого шаблона.

Параметр коммутатора может быть сокращен; можно использовать любую отдельную ведущую часть параметра. Например, ‑Regex, , ‑Rege‑Reg‑Re, и ‑R эквивалентны.

Если заданы конфликтующие параметры коммутатора, лексически окончательный параметр преобладает. Наличие ‑Exact отключает -Regex и -Wildcard; оно не влияет ‑Caseна, однако.

Если задан параметр‑Parallel switch, то определяется поведение.

Параметр switch-parameter‑Parallel разрешен только в рабочем процессе (§8.10.2).

Если шаблон является выражением script-block-expression, этот блок вычисляется и результат преобразуется в логическое значение при необходимости. Если результат имеет значение $true, соответствующий блок инструкции выполняется; в противном случае это не так.

Если условие переключения обозначает несколько значений, параметр применяется к каждому значению в лексическом порядке с помощью правил, описанных выше для условия коммутатора, которое обозначает одно значение. Каждая инструкция switch имеет собственный перечислитель $switch (§2.3.2.2, §4.5.16), который существует только во время выполнения этого коммутатора.

Оператор switch может иметь метку, и она может содержать метки и неназначенные разрывы (§8.5.1) и продолжить (§8.5.2) операторов.

Если параметр-условие-Fileswitch-filename, вместо итерации значений в выражении переключение выполняет итерацию значений в файле, указанном параметром switch-filename. Файл считывает строку за раз с каждой строкой, содержащей значение. Символы конца строки не включаются в значения.

Примеры.

$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 Инструкция try/finally

Синтаксис:

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

Описание:

Инструкция try предоставляет механизм перехвата исключений, возникающих во время выполнения блока. Инструкция try также предоставляет возможность указывать блок кода, который всегда выполняется при выходе элемента управления из инструкции try. Процесс создания исключения с помощью инструкции throw описан в разделе §8.5.3.

Блок try — это блок инструкции, связанный с инструкцией try. Блок catch — это блок инструкции, связанный с предложением catch-. Наконец , блокинструкции , связанный с предложением, наконец, является блоком инструкции.

Предложение catch-безсписка catch-type называется общим предложением catch.

Каждое предложение catch являетсяобработчиком исключений, а предложение catch-type-list содержит тип вызываемого исключения — это соответствующее предложение catch. Общее предложение catch соответствует всем типам исключений.

Хотя предложения catch-и, наконец, являются необязательными, по крайней мере один из них должен присутствовать.

Обработка вызываемого исключения состоит из многократного вычисления следующих шагов до тех пор, пока не будет найдено предложение catch, соответствующее исключению.

  • В текущей области выполняется анализ каждой инструкции try, включающей точку броска. Для каждого оператора try S, начиная с самого внутреннего оператора try и заканчивая внешним оператором try, оцениваются следующие действия:

    • try Если блок S заключает точку броска и если S имеет одно или несколько предложений catch, предложения catch проверяются в лексическом порядке, чтобы найти подходящий обработчик для исключения. Первое предложение catch, указывающее тип исключения или базовый тип типа исключения, считается совпадением. Общее предложение catch считается совпадением для любого типа исключения. Если находится соответствующее предложение catch, обработка исключений завершается путем передачи элемента управления в блок этого предложения catch. В предложении catch для сопоставления переменная $_ содержит описание текущего исключения.

    • В противном случае, если блок или catch блок S заключает точку броска и если tryУ S есть finally блок, элемент управления передается в наконец-то блок. Если блок finally создает другое исключение, обработка текущего исключения завершается. В противном случае, когда элемент управления достигает конца блока, обработка текущего finally исключения продолжается.

  • Если обработчик исключений не был расположен в текущей области, описанные выше действия повторяются для заключающей области с точкой вызова, соответствующей инструкции, из которой была вызвана текущая область.

  • Если обработка исключений заканчивается завершением всех областей, указывая, что обработчик для исключения не существует, то поведение не указано.

Чтобы предотвратить неустранимые предложения catch в блоке try, предложение catch может не указывать тип исключения, равный или производный от типа, указанного в предыдущем предложении catch в том же блоке try.

Операторы блока finally всегда выполняются, когда управление выходит из оператора try. Это верно, происходит ли передача элемента управления в результате нормального выполнения, в результате выполнения breakcontinueинструкции или return в результате исключения, выброшенного из try инструкции.

Если исключение возникает во время выполнения блока, исключение создается для следующей finally инструкции, try заключающей в себя. Если другое исключение было в процессе обработки, это исключение будет потеряно. Процесс создания исключения рассматривается далее в описании инструкции throw .

try операторы могут совместно существовать с trap операторами; дополнительные сведения см. в разделе "8.8 ".

Примеры.

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

Каждое исключение возникает как исключение System.Management.Automation.RuntimeException. Если в try блоке имеются предложения catchс определенным типом, свойство InnerException исключения проверяется, чтобы попытаться найти совпадение, например с указанным выше типомSystem.IndexOutOfRangeException.

8.8 Оператор ловушки

Синтаксис:

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

Описание:

Оператор trap с типом и без литералов аналогиен catch блоку (§8.7) с списком типа catch и без них соответственно, за исключением того, что trap оператор может перехватывать только один тип одновременно.

Несколько trap операторов можно определить в одном блоке инструкций, и их порядок определения не имеет значения. Если два trap оператора с одним и тем же типом литерала определены в одной области, лексически первый используется для обработки исключения соответствующего типа.

catch В отличие от блока, trap оператор точно соответствует типу исключения; не выполняется сопоставление производных типов.

При возникновении исключения, если trap в текущей области отсутствует соответствующая инструкция, в области вызова выполняется поиск соответствующей инструкции ловушки, которая может включать поиск в вызывающем скрипте, функции или фильтре, а затем в вызывающем объекте и т. д. Если поиск заканчивается всеми областями, указывая, что обработчик для исключения не существует, то поведение не указано.

Текст trapинструкции выполняется только для обработки соответствующего исключения; в противном случае выполнение передается по нему.

trapЕсли оператор-текст инструкции завершается обычно, по умолчанию объект ошибки записывается в поток ошибок, исключение считается обработанным, и выполнение продолжается с инструкцией сразу после инструкции в области, содержащей trap инструкцию, которая сделала исключение видимым. Причина исключения может находиться в команде, вызываемой командой, содержащей инструкцию trap .

Если последняя инструкция, выполненная в trapтексте инструкции , продолжается (§8.5.2), запись объекта ошибки в поток ошибок подавляется, и выполнение продолжается с инструкцией сразу после оператора в области, содержащей инструкцию ловушки, которая сделала исключение видимым. Если окончательный оператор, выполняемый в тексте инструкции, прерывается (§8.5.1), запись объекта ошибки в trapпоток ошибок подавляется, а исключение создается повторно.

trap В инструкции переменная $_ содержит описание текущей ошибки.

Рассмотрим случай, в котором исключение, возникающее из блока try , не имеет catch соответствующего блока, но оператор сопоставления trap существует на более высоком уровне блока. try После завершения trap предложения блока оператор получает контроль, даже если у любой родительской области есть соответствующий catch блок. trap Если инструкция определена внутри try самого блока, и этот try блок имеет соответствующий catch блок, trap оператор получает управление.

Примеры.

В следующем примере объект ошибки записывается, и выполнение продолжается с инструкцией сразу после той, которая вызвала ловушку; то есть "Готово" записывается в конвейер.

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

В следующем примере запись объекта ошибки подавляется, и выполнение продолжается с инструкцией сразу после той, которая вызвала ловушку; то есть "Готово" записывается в конвейер.

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

В следующем примере запись объекта ошибки подавляется, и исключение создается повторно.

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

В следующем примере операторы ловушки и создания исключений находятся в той же области. После перехвата и обработки исключения выполнение возобновляется с записью 1 в конвейер.

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

В следующем примере операторы ловушки и создания исключений находятся в разных областях. После перехвата и обработки исключения выполнение возобновляется с записью 2 (не 1) в конвейер.

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

8.9 Инструкция данных

Синтаксис:

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

Описание:

Оператор данных создает раздел данных, сохраняя данные этого раздела отдельно от кода. Это разделение поддерживает такие средства, как отдельные файлы ресурсов строки для текста, такие как сообщения об ошибках и строки справки. Она также помогает поддерживать интернационализацию, упрощая изоляцию, поиск и обработку строк, которые будут переведены на разные языки.

Скрипт или функция могут содержать ноль или больше разделов данных.

Блок инструкций раздела данных ограничен следующими функциями PowerShell:

  • Все операторы, кроме -match
  • Инструкция if
  • Следующие автоматические переменные: $PSCulture, $PSUICulture, $true, $falseи $null.
  • Комментарии
  • Трубопроводы
  • Операторы, разделенные точкой с запятой (;)
  • Литералы
  • Вызовы командлета ConvertFrom-StringData
  • Любые другие командлеты, определенные с помощью параметра SupportedCommand

ConvertFrom-StringData Если используется командлет, пары "ключ-значение" можно выразить с помощью любой формы строкового литерала. Однако расширяемые строковые литеральныеs и expandable-here-string-литералыне должны содержать подстановки переменных или расширения вложенных выражений.

Примеры.

Параметр SupportedCommand указывает, что указанные командлеты или функции создают только данные. Например, следующий раздел данных содержит командлет, написанный пользователем, ConvertTo-Xmlкоторый форматирует данные в XML-файле:

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

Рассмотрим следующий пример, в котором раздел данных содержит ConvertFrom-StringData команду, которая преобразует строки в хэш-таблицу, значение которой $messagesприсваивается.

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

Ключи и значения хэш-таблицы доступны с помощью $messages.Greeting, $messages.Yesи $messages.Noсоответственно.

Теперь это можно сохранить как ресурс английского языка. Ресурсы немецкого и испанского языка можно создавать в отдельных файлах со следующими разделами данных:

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

Если имя данных присутствует, он называет переменную (без использования ведущих $) в которой должно храниться значение инструкции данных. В частности, $name = data { ... } эквивалентен data name { ... }.

Определения функций 8.10

Синтаксис:

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

Описание:

Определение функции указывает имя функции, фильтра или рабочего процесса, а также имена параметров, если таковые есть. Он также содержит ноль или больше инструкций, выполняемых для достижения цели этой функции.

Каждая функция — это экземпляр класса System.Management.Automation.FunctionInfo.

Функции фильтра 8.10.1

В то время как обычная функция выполняется один раз в конвейере и обращается к входной коллекции с помощью $inputфильтра, фильтр является специальной функцией, которая выполняется один раз для каждого объекта в коллекции входных данных. Объект, обрабатываемый в данный момент, доступен с помощью переменной $_.

Фильтр без именованных блоков (§8.10.7) эквивалентен функции с блоком процесса, но без любого блока начала или конца.

Рассмотрим следующее определение функции фильтра и вызовы:

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

Каждый фильтр является экземпляром класса System.Management.Automation.FilterInfo (§4.5.11).

Функции рабочего процесса 8.10.2

Функция рабочего процесса похожа на обычную функцию с определенной семантикой реализации. Функция рабочего процесса преобразуется в последовательность действий Windows Workflow Foundation и выполняется в подсистеме Windows Workflow Foundation.

Обработка аргументов 8.10.3

Рассмотрим следующее определение функции Get-Power:

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

Эта функция имеет два параметра и $Base$Exponent. Он также содержит набор операторов, которые для неотрицательных экспонентных значений, вычислений $Base^$Exponent^ и возврата результата вызывающему объекту Get-Power.

Когда начинается выполнение скрипта, функции или фильтра, каждый параметр инициализируется в соответствующее значение аргумента. Если соответствующий аргумент отсутствует и значение по умолчанию (§8.10.4) указано, используется это значение; в противном случае используется значение $null . Таким образом, каждый параметр является новой переменной так же, как если бы она была инициализирована назначением в начале блока скрипта.

Если параметр скрипта содержит ограничение типа (например [long] , и [int] выше), значение соответствующего аргумента преобразуется в этот тип при необходимости; в противном случае преобразование не происходит.

Когда скрипт, функция или фильтр начинает выполнение, переменная $args определяется внутри нее как неограниченный 1-мерный массив, который содержит все аргументы, не привязанные к имени или позиции, в лексическом порядке.

Рассмотрим следующее определение и вызовы функции:

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

Дополнительные сведения о привязке параметров см. в разделе §8.14.

Инициализаторы параметров 8.10.4

Объявление параметра p может содержать инициализатор, в этом случае значение инициализатора используется для инициализации p , предоставленного p, не привязан к каким-либо аргументам в вызове.

Рассмотрим следующее определение и вызовы функции:

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

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

8.10.5 Ограничение типа [switch]

При передаче параметра коммутатора соответствующий параметр в команде должен быть ограничен параметром типа. Параметр типа имеет два значения: True и False.

Рассмотрим следующее определение и вызовы функции:

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 Конвейеры и функции

При использовании скрипта, функции или фильтра в конвейере коллекция значений передается в этот скрипт или функцию. Скрипт, функция или фильтр получает доступ к этой коллекции через перечислитель $input (§2.3.2.2, §4.5.16), который определяется для записи в этот скрипт, функцию или фильтр.

Рассмотрим следующее определение и вызовы функции:

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 Именованные блоки

Инструкции в блоке скрипта могут принадлежать одному большому неназваемому блоку, или они могут быть распределены по одному или нескольким именованным блокам. Именованные блоки позволяют настраиваемую обработку коллекций, поступающих из конвейеров; именованные блоки можно определить в любом порядке.

Операторы в блоке начала (т. е. один, помеченный ключевым словом begin), выполняются один раз, прежде чем будет доставлен первый объект конвейера.

Операторы в блоке процесса (т. е. один, помеченный процессом ключевого слова), выполняются для каждого объекта конвейера, доставленного. ($_ предоставляет доступ к текущему объекту, обрабатываемму из входной коллекции, поступающей из конвейера.) Это означает, что если коллекция элементов нуля отправляется через конвейер, блок обработки не выполняется вообще. Однако если скрипт или функция вызывается вне контекста конвейера, этот блок выполняется ровно один раз и $_ имеет значение $null, так как текущий объект коллекции отсутствует.

Операторы в конце блока (т. е. один помеченный с помощью конца ключевого слова) выполняются один раз после доставки последнего объекта конвейера.

Блок dynamicparam версии 8.10.8

Подразделы §8.10 до сих пор имеют дело со статическими параметрами, которые определяются как часть исходного кода. Также можно определить динамические параметры с помощью блока dynamicparam, другой формы именованного блока (§8.10.7), помеченной ключевым словом dynamicparam. Большая часть этого механизма определена.

Динамические параметры — это параметры командлета, функции, фильтра или скрипта, доступные только в определенных условиях. Одним из таких случаев является параметр кодирования командлета Set-Item .

В блоке инструкций используйте инструкцию if, чтобы указать условия, в которых параметр доступен в функции. Используйте командлет New-Object , чтобы создать объект определенного реализацией типа для представления параметра и указать его имя. Кроме того, используйте New-Object для создания объекта другого определяемого реализацией типа для представления атрибутов, определенных реализацией параметра.

В следующем примере показана функция со стандартными параметрами с именем Name и Path, а также необязательным динамическим параметром с именем DP1. Параметр DP1 находится в наборе параметров PSet1 и имеет тип Int32. Параметр DP1 доступен в функции Sample, только если значение параметра Path содержит HKLM:, указывающее, что он используется на 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
        }
    }
}

Тип, используемый для создания объекта для представления динамического параметра System.Management.Automation.RuntimeDefinedParameter.

Тип, используемый для создания объекта для представления атрибутов параметра System.Management.Automation.ParameterAttribute.

Определяемые реализацией атрибуты параметра включают обязательный, position и ValueFromPipeline.

Блок 8.10.9 param

Парам-блок предоставляет альтернативный способ объявления параметров. Например, следующие наборы объявлений параметров эквивалентны:

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

Парам-блок разрешает список атрибутов в блоке param- в то время как объявление function-parameter-not.

Скрипт может иметь парам-блок , но не объявление function-parameter-declaration. Определение функции или фильтра может иметь объявление -function-parameter-declaration или param-block, но не оба.

Рассмотрим следующий пример:

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

Один параметр, $ComputerNameимеет тип string[], требуется, и он принимает входные данные из конвейера.

Дополнительные примеры см. в разделе "12.3.7".

8.11 Параллельная инструкция

Синтаксис:

parallel-statement:
    *parallel* statement-block

Параллельная инструкция содержит ноль или больше инструкций, выполняемых в определенной реализации.

Параллельная инструкция разрешена только в рабочем процессе (§8.10.2).

8.12 Оператор последовательности

Синтаксис:

sequence-statement:
    *sequence* statement-block

Оператор последовательности содержит ноль или несколько инструкций, выполняемых в определенной реализации.

Оператор последовательности разрешен только в рабочем процессе (§8.10.2).

8.13 Оператор inlinescript

Синтаксис:

inlinescript-statement:
    inlinescript statement-block

Оператор inlinescript содержит ноль или несколько инструкций, выполняемых в определенной реализации.

Оператор inlinescript разрешен только в рабочем процессе (§8.10.2).

Привязка параметров 8.14

При вызове скрипта, функции, фильтра или командлета каждый аргумент может быть привязан к соответствующему параметру по позиции, с первым параметром с нулевым положением.

Рассмотрим следующий фрагмент определения для вызываемой Get-Powerфункции и вызовы к ней:

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

При вызове скрипта, функции, фильтра или командлета аргумент может быть привязан к соответствующему параметру по имени. Это делается с помощью параметра с аргументом, который является аргументом, который является именем параметра с ведущим дефисом (-), за которым следует связанное значение для этого аргумента. Используемое имя параметра может иметь любое нечувствительное правописание регистра и может использовать любой префикс, который однозначно обозначает соответствующий параметр. При выборе имен параметров не используйте имена общих параметров.

Рассмотрим следующие вызовы функции 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

С другой стороны, вызовы следующей функции

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

должен использовать параметры -Side1 и -Side2, так как нет префикса, который однозначно обозначает этот параметр.

Одно и то же имя параметра нельзя использовать несколько раз с различными связанными значениями аргументов или без нее.

Параметры могут иметь атрибуты (§12). Сведения об отдельных атрибутах см. в разделах в разделе §12.3. Сведения о наборах параметров см. в разделе §12.3.7.

Скрипт, функция, фильтр или командлет могут получать аргументы с помощью командной строки вызова, из конвейера или из обоих. Ниже приведены шаги для разрешения привязки параметров:

  1. Привязка всех именованных параметров, а затем
  2. Привязка позиционных параметров, а затем
  3. Привязка из конвейера по значению (§12.3.7) с точным совпадением, а затем
  4. Привязка из конвейера по значению (§12.3.7) с преобразованием, а затем
  5. Привязка из конвейера по имени (§12.3.7) с точным совпадением, а затем
  6. Привязка из конвейера по имени (§12.3.7) с преобразованием

Некоторые из этих шагов включают преобразование, как описано в разделе 6. Однако набор преобразований, используемых в привязке, не совпадает с тем, что используется в преобразованиях языка. Конкретно

  • Хотя значение $null может быть приведение к логическое значение, $null не может быть привязано к bool.
  • Когда значение $null передается параметру switch для командлета, оно обрабатывается как будто $true передано. Однако при передаче в параметр коммутатора для функции он обрабатывается как $false если бы он был передан.
  • Параметры типа bool или switch могут привязаться только к числовым или логическим аргументам.
  • Если тип параметра не является коллекцией, но аргумент является какой-то коллекцией, преобразование не выполняется, если тип параметра не является объектом или PsObject. (Основной точкой этого ограничения является запрет на преобразование коллекции в строковый параметр.) В противном случае выполняется попытка обычных преобразований.

Если тип параметра имеет IList значение или ICollection<T>выполняется попытка выполнить только эти преобразования с помощью конструктора, op_Implicit и op_Explicit. Если таких преобразований нет, используется специальное преобразование для параметров типа collection, включающее IListICollection<T>и массивы.

При возможности позиционные параметры предпочитают быть привязаны без преобразования типов. Например

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"