8. 진술

편집 참고 사항

중요하다

Windows PowerShell 언어 사양 3.0 2012년 12월에 게시되었으며 Windows PowerShell 3.0을 기반으로 했습니다. 이 사양은 PowerShell의 현재 상태를 반영하지 않습니다. 현재 상태를 반영하도록 이 설명서를 업데이트할 계획은 없습니다. 이 설명서는 기록 참조를 위해 여기에 제공됩니다.

사양 문서는 Microsoft 다운로드 센터 Microsoft Word 문서로 사용할 수 있습니다. https://www.microsoft.com/download/details.aspx?id=36389 Word 문서가 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) { }

루프가 5번 반복되지만 파이프라인에 기록되지 않습니다. 구문의 값이 $null입니다.

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

루프는 5번 반복되며, 각 반복마다 int파이프라인에 $i 값을 씁니다. 문장의 값은 길이 5의 object[]이다.

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

루프가 5번 반복되지만 파이프라인에 기록되지 않습니다. 문장의 값은 $null입니다.

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

루프는 다섯 번 반복되며, 각 값이 파이프라인에 기록됩니다. 문장의 값은 길이 5의 object[]이다.

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

루프는 한 번 반복됩니다. 명령문의 값은 값이 2인 int입니다.

다음은 몇 가지 다른 예입니다.

# 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참조하세요.

파이프라인의 첫 번째 명령은 명령식 또는 명령 호출입니다. 명령 호출은 일반적으로 명령 이름이라는 bare 식별자로 시작합니다. 명령 요소 명령에 대한 인수 목록을 나타냅니다. 줄바꿈 또는 이스케이프되지 않은 세미콜론은 파이프라인을 종료합니다.

명령 호출은 명령 이름 뒤에 0개 이상의 인수로 구성됩니다. 인수를 제어하는 규칙은 다음과 같습니다.

  • 표현식이 아니지만, 이스케이프되지 않은 공백이 포함된 임의의 텍스트를 포함하는 인수는 큰따옴표로 묶인 것처럼 처리됩니다. 문자 대소문자를 유지합니다.

  • 변수 대체 및 하위 식 확장(§2.3.5.2)은 expandable-string-literal내와 expandable-here-string-literal내에서 발생합니다.

  • 따옴표 안의 텍스트를 사용하면 선행, 후행 및 포함된 공백을 인수 값에 포함할 수 있습니다. [참고: 따옴표 붙은 인수에 공백이 있으면 단일 인수가 여러 인수로 바뀌지 않습니다. 끝 주]

  • 인수 주위에 괄호를 배치하면 원래 식의 텍스트 대신 결과가 전달되어 해당 식이 계산됩니다.

  • 매개 변수(§2.3.4)처럼 [switch] 보이지만 의도되지 않은 인수를 전달하려면 해당 인수를 따옴표로 묶습니다.

  • [switch] 형식 제약 조건(§8.10.5)이 있는 매개 변수에 일치하는 인수를 지정할 때, 인수 이름이 단독으로 표시되면 해당 매개 변수가 $true으로 설정됩니다. 그러나 인수에 접미사를 추가하여 매개 변수의 값을 명시적으로 설정할 수 있습니다. 예를 들어 형식이 제한된 매개 변수 p지정된 경우 -p:$true 인수는 p를 True로 설정하고 -p:$false p를 False로 설정합니다.

  • -- 인수는 그 다음에 오는 모든 인수가 마치 큰따옴표로 둘러싸인 것처럼 있는 그대로 전달되어야 한다는 것을 나타냅니다.

  • --% 인수는 해당 인수 다음에 있는 모든 인수를 최소한의 구문 분석 및 처리로 전달해야 임을 나타냅니다. 이 인수를 '말 그대로' 매개변수라고 합니다. 축자 매개 변수 뒤의 인수는 구문적으로 유효한 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), exit (§8.5.5), try (§8.7) 및 trap (§8.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

묘사:

파이프라인을 제어하는 표현은 반드시 bool 유형이어야 하거나 그 유형으로 암시적으로 변환 가능해야 합니다. else 절 선택 사항입니다. elseif 절0개 이상의 있을 수 있습니다.

최상위 파이프라인이 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

묘사:

제어 식 while 조건식은 형식이 부울이어야 하거나 해당 형식으로 암시적으로 변환할 수 있어야 합니다. 루프 본문은 문 블록으로 구성되어 있으며, 제어 식이 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

묘사:

제어 식 while 조건식은 형식이 부울이어야 하거나 해당 형식으로 암시적으로 변환할 수 있어야 합니다. while 형식에서는 제어 식이 True를 테스트하는 동안 문 블록구성된 루프 본문이 반복적으로 실행됩니다. until 폼에서 제어 식이 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

묘사:

제어 식 의 조건은 부울 타입이거나 해당 타입으로 암시적으로 변환 가능해야 합니다. 문장 블록로 구성된 루프 본문은 제어 표현식이 True인지 검사하는 동안 반복적으로 실행됩니다. 제어 식은 루프 본문을 실행할 때마다 평가됩니다.

for-initializer 제어 식의 첫 번째 평가 전에 평가됩니다. 식 for-initializer는 부작용만을 평가하기 위해 실행되며, 생성된 모든 값은 무시되고 파이프라인에 기록되지 않습니다.

매 루프 본문 실행 후 반복기의 표현식 이 평가됩니다. for-iterator의 식 는 부작용만을 위해 평가되며, 생성된 값은 모두 폐기되고 파이프라인에 기록되지 않습니다.

for-condition이 생략될 경우, 제어 표현은 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값을 지정하면 파이프라인 0개 요소의 컬렉션으로 처리됩니다.

foreach 매개 변수-parallel 지정하면 동작이 구현에 정의됩니다.

foreach 매개 변수‑parallel 워크플로(§8.10.2)에서만 허용됩니다.

모든 foreach 문에는 루프가 실행되는 동안에만 존재하는 고유한 열거자 $foreach(§2.3.2.2, §4.5.16)이 있습니다.

파이프라인에 의해 생성된 객체는 명령 블록이 실행되기 전에 수집됩니다. 그러나 ForEach-Object cmdlet을 사용하면 생성되는 각 개체에서 문 블록 실행됩니다.

예제:

$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 break 문

묘사:

레이블 식 있는 break 문을 레이블이 지정된 break 문이라고 합니다. 레이블 식이 없는 break 문은 레이블이 지정되지 않은 중단 문이라고 한다.

트랩 문이 아닌 반복문(§8.4) 내에서 레이블이 지정되지 않은 break 문은 가장 작은 범위의 반복문에서 그 반복문의 실행을 종료합니다. switch 문(§8.6) 내에서 직접 레이블이 지정되지 않은 break 문은 현재 스위치의 스위치 조건대한 패턴 일치를 종료합니다. 트랩 문 내에서 중단을 사용하는 방법에 대한 자세한 내용은 (§8.8)를 참조하세요.

반복 문 또는 switch 문은 필요에 따라 하나의 문 레이블(§8.1.1)으로 바로 앞에 올 수 있습니다. 이러한 문 레이블은 레이블이 지정된 break 문의 대상으로 사용될 수 있으며, 이 경우 해당 문은 대상 바깥쪽 반복 문의 실행을 종료합니다.

레이블이 지정된 중단은 로컬 범위에서 해결될 필요가 없습니다. 일치하는 레이블을 찾기 위한 검색은 스크립트와 함수 호출 경계를 넘어 호출 스택을 따라 계속 진행될 수 있습니다. 일치하는 레이블이 없으면 현재 명령 호출이 종료됩니다.

지정된 레이블 식의 이름은 상수 값일 필요가 없습니다.

레이블 식단항식인 경우, 문자열로 변환됩니다.

예제:

$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 사용은 §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 절finally 절이 실행된 후에 다시 throw됩니다.

파이프라인이 있는 경우, 발생하는 예외의 유형은 구현에 따라 정의됩니다.

예외가 발생하면, 제어권이 예외를 처리할 수 있는 바깥쪽 try 문에 있는 첫 번째 catch 절로 전달됩니다. 처음 예외가 발생하는 위치를 throw 지점이라고 합니다. 예외가 발생하면, 예외와 일치하는 catch 절을 찾을 때까지, 또는 찾을 수 없을 때까지 §8.7에 설명된 단계를 반복적으로 따릅니다.

예제:

throw
throw 100
throw "No such record in file"

파이프라인이 생략되고 throw 문이 catch 절내에 없을 경우, "ScriptHalted"라는 텍스트가 파이프라인에 기록되며, 발생한 예외의 유형은 System.Management.Automation.RuntimeException입니다.

파이프라인이 있는 경우, 예외가 System.Management.Automation.RuntimeException형식의 객체로 래핑되며, 여기에는 예외에 대한 정보가 System.Management.Automation.ErrorRecord 개체로 포함되며 $_를 통해 접근할 수 있습니다.

예제 1: throw 123RuntimeException유형의 예외를 발생시킵니다. catch 블록 내에서 $_.TargetObject는 내부에 래핑된 개체를 포함하고 있으며, 이 경우 값이 123인 System.Int32입니다.

예제 2: throw "xxx"이(가) RuntimeException형식의 예외를 발생시킵니다. catch 블록 내에서 $_.TargetObject는 내부에 래핑된 개체를 포함하고 있으며, 이 경우 값이 "xxx"인 System.String이 포함되어 있습니다.

예제 3: throw 10,20RuntimeException유형의 예외를 발생시킵니다. catch 블록 내에서 $_.TargetObject은 내부에 래핑된 개체를 담고 있습니다. 이 경우 개체는 System.Object[]이며, 제약이 없는 두 요소의 배열로, SystemInt32 값을 가지는 10과 20입니다.

8.5.4 반환문

묘사:

문은 (있다면)파이프라인에서 로 지정된 값을 파이프라인에 작성하고, 함수 또는 스크립트의 호출자에게 제어권을 반환합니다. 함수 또는 스크립트에는 0개 이상의 return 문이 있을 수 있습니다.

실행이 함수의 닫는 중괄호에 도달하면 return가 없는 경우, 암시적인 이 가정됩니다.

return 문은 프로그래머가 다른 프로그램 언어에서 할 수 있는 것처럼 자신을 표현할 수 있도록 허용하는 약간의 "구문적 설탕"입니다. 그러나 함수나 스크립트에서 반환되는 값은 실제로 그 함수나 스크립트에 의해 파이프라인에 기록된 모든 값과 파이프라인지정된 값들입니다. 스칼라 값만 파이프라인에 기록되는 경우 해당 형식은 반환되는 값의 형식입니다. 그렇지 않으면 반환 형식은 파이프라인에 기록된 모든 값을 포함하는 제약이 없는 1차원 배열입니다.

예제:

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 종료 문장

묘사:

exit 문은 현재 스크립트를 종료하고 호스트 환경 또는 호출 스크립트에 컨트롤 및 종료 코드를 반환합니다. 파이프라인이 제공되면, 지정된 값은 필요시 int로 변환됩니다. 이러한 변환이 없거나 파이프라인 생략된 경우 int 값 0이 반환됩니다.

예제:

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(기본 스위치 절)로 시작해야 합니다. 스위치에는 0개 또는 1개의 default 스위치 절과 기본이 아닌 0개 이상의 다른 스위치 절이 포함되어야 합니다. Switch 절은 어느 순서로든 작성될 수 있습니다.

여러 패턴의 값이 같을 수 있습니다. 패턴은 리터럴일 필요가 없으며 스위치에는 다른 형식의 패턴이 있을 수 있습니다.

스위치 조건 값이 패턴 값과 일치하면 해당 패턴의 문 블록 실행됩니다. 여러 패턴 값이 스위치 조건값과 일치하는 경우 일치하는 각 패턴의 문 블록 어휘 순서로 실행됩니다. 이러한 문 블록break 문(§8.5.1)이 포함되지 않는 한 어휘 순서로 실행됩니다.

스위치 조건의 값이 어떤 패턴 값과도 일치하지 않는 경우, default 스위치 절이 있으면 그에 따라 문 블록이(가) 실행됩니다. 그렇지 않으면 해당 스위치 조건에 대한 패턴 일치가 종료됩니다.

스위치는 중첩될 수 있으며 각 스위치에는 고유한 스위치 절 집합이 있습니다. 이러한 경우 switch 절은 현재 범위에 있는 가장 안쪽 스위치에 속합니다.

문 블록에 진입할 때, 해당 $_로 제어를 이동시킨 스위치 조건의 값이 에 자동으로 할당됩니다. $_문 블록switch-clause-condition에서도 사용할 수 있습니다.

비 문자열의 일치는 같음을 테스트하여 수행됩니다(§7.8.1).

문자열을 비교할 때, 기본적으로 대/소문자를 구분하지 않습니다. 스위치 매개 변수가 존재하면 비교가 대/소문자를 구분합니다.

패턴에는 와일드카드 문자(§3.15)가 포함될 수 있으며, 이 경우 스위치 매개 변수-Wildcard 가 있는 경우에만 와일드카드 문자열 비교가 수행됩니다. 기본적으로 비교는 대/소문자를 구분하지 않습니다.

패턴은 정규식(§3.16)을 포함할 수 있으며, 이 경우 정규식 문자열 비교가 수행되지만 스위치 매개 변수-Regex 있는 경우에만 수행됩니다. 기본적으로 비교는 대/소문자를 구분하지 않습니다. -Regex이(가) 존재하고 패턴이 일치하면, 그 패턴에 대해 $Matches문 블록에서 이(가) 정의됩니다.

스위치 매개 변수 축약될 수 있습니다. 매개 변수의 모든 고유 선행 부분을 사용할 수 있습니다. 예를 들어 ‑Regex, ‑Rege, ‑Reg, ‑Re‑R 동일합니다.

충돌하는 스위치-파라미터이 지정될 경우, 어휘적으로 가장 마지막의 것이 우선합니다. ‑Exact 있으면 -Regex-Wildcard가 비활성화됩니다. 그러나 ‑Case에는 영향을 주지 않습니다.

스위치 매개 변수‑Parallel 지정하면 동작이 구현에 정의됩니다.

스위치 매개 변수‑Parallel 워크플로(§8.10.2)에서만 허용됩니다.

패턴이 스크립트 블록 식경우 해당 블록이 평가되고 필요한 경우 결과가 bool로 변환됩니다. 결과에 $true값이 있으면 해당 문 블록 실행됩니다. 그렇지 않으면 그렇지 않습니다.

스위치 조건 여러 값을 지정하는 경우 스위치는 단일 값을 지정하는 스위치 조건 대해 위에서 설명한 규칙을 사용하여 어휘 순서대로 각 값에 적용됩니다. 모든 switch 문에는 해당 스위치가 실행되는 동안에만 존재하는 고유한 열거자 $switch(§2.3.2.2, §4.5.16)이 있습니다.

switch 문에는 레이블이 있을 수 있으며 레이블이 지정되고 레이블이 지정되지 않은 중단(§8.5.1) 및 continue(§8.5.2) 문이 포함될 수 있습니다.

스위치 조건-File스위치 파일 이름인 경우, 표현식의 값을 반복하는 대신, 스위치는 스위치 파일 이름로 지정된 파일 안의 값을 반복합니다. 파일은 각 줄이 하나의 값을 포함하도록 한 줄씩 읽습니다. 줄 종결자 문자는 값에 포함되지 않습니다.

예제:

$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 절과 연결된 문 블록입니다. finally 블록finally 절에 연결된 문 블록입니다.

catch-type-list를 포함하지 않는 catch 절일반 catch 절이라고부릅니다.

catch 절예외 처리기이며, catch-type-list에 발생한 예외의 유형이 포함된 catch 절일치하는 catch 절입니다. 일반 catch 절은 모든 예외 형식과 일치합니다.

catch 절finally 절 는 선택 사항이지만, 적어도 하나는 반드시 포함되어야 합니다.

던져진 예외의 처리는 예외에 맞는 catch 절이 발견될 때까지 다음 단계를 반복적으로 평가하는 것으로 구성됩니다.

  • 현재 범위에서 throw 지점을 둘러싸는 각 try 문이 검사됩니다. 가장 안쪽 try 문부터 시작하여 가장 바깥쪽 try 문으로 끝나는 각 try 문 S대해 다음 단계가 평가됩니다.

    • try 블록이 throw 지점을 묶고 S 하나 이상의 catch 절이 있는 경우 catch 절은 어휘 순서로 검사되어 예외에 적합한 처리기를 찾습니다. 예외 형식 또는 예외 형식의 기본 형식을 지정하는 첫 번째 catch 절은 일치 항목으로 간주됩니다. 일반적인 catch 절은 모든 예외 유형에 대해 일치하는 것으로 간주됩니다. 일치하는 catch 절이 있으면 컨트롤을 해당 catch 절의 블록으로 전송하여 예외 처리가 완료됩니다. 일치하는 catch 절 내에서 변수 $_ 현재 예외에 대한 설명을 포함합니다.

    • 그렇지 않으면 trycatch 블록 또는 블록이 throw 지점을 포함하고, Sfinally 블록이 있는 경우, 제어가 최종 블록으로 전달됩니다. finally 블록이 다른 예외를 throw하면 현재 예외 처리가 종료됩니다. 그렇지 않으면 컨트롤이 finally 블록의 끝에 도달하면 현재 예외 처리가 계속됩니다.

  • 예외 처리기가 현재 범위에서 발견되지 않은 경우, 위의 단계는 현재 범위가 호출된 문에 해당하는 throw 지점이 있는 바깥쪽 범위에 대해 다시 반복됩니다.

  • 예외 처리가 모든 범위를 종료하고 예외에 대한 처리기가 없음을 나타내는 경우 동작이 지정되지 않습니다.

try 블록에서 도달할 수 없는 catch 절을 방지하기 위해, catch 절은 동일한 try 블록 내의 이전 catch 절에 지정된 형식과 같거나 파생된 예외 형식을 지정해서는 안 됩니다.

finally 블록의 문은 제어가 try 문을 벗어날 때 항상 실행됩니다. 컨트롤 전송은 정상적인 실행의 결과로 발생하든, break, continue, 또는 return 문을 실행한 결과로 발생하든, 또는 try 문에서 예외가 throw된 결과로 발생하든 관계없이 마찬가지입니다.

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있는 경우 예외의 InnerException 속성을 검사하여 위의 System.IndexOutOfRangeException 형식과 같은 일치 항목을 찾아 봅니다.

8.8 트랩 문장

구문:

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

묘사:

trap의 유무에 관계없이 문은 catch 문이 한 번에 하나의 형식만을 트래핑할 수 있다는 점을 제외하고, 각각 catch-type-list을 포함하거나 사용하지 않는 블록(trap)과 유사합니다.

하나의 trap에서 여러 개의 문을 정의할 수 있으며, 해당 정의의 순서는 중요하지 않습니다. 동일한 trap를 가진 문 두 개가 동일한 범위에 정의된 경우, 사전적으로 첫 번째 문장이 일치하는 유형의 예외를 처리하는 데 사용됩니다.

catch 블록과 달리 trap 문은 예외 형식과 정확히 일치합니다. 파생 형식 일치가 수행되지 않습니다.

예외가 발생하면 현재 범위에 일치하는 trap 문이 없으면 바깥쪽 범위에서 일치하는 트랩 문을 검색합니다. 여기에는 호출 스크립트, 함수 또는 필터, 호출자 등을 찾는 작업이 포함될 수 있습니다. 조회 작업이 모든 범위를 종료하게 되어 예외에 대한 처리기가 없음을 나타내는 경우, 동작은 정의되지 않습니다.

trap 문의 문 본문은 오류가 발생했을 때 예외를 처리하기 위해서만 실행됩니다. 그렇지 않으면 해당 부분을 건너뜁니다.

trap 문 본문이 정상적으로 종료되면 기본적으로 오류 개체가 오류 스트림에 기록되고, 예외가 처리된 것으로 간주되며, 예외를 표시한 trap 문이 포함된 범위의 바로 다음 문으로 실행이 계속됩니다. 예외의 원인은 trap 문을 포함하는 명령에서 호출된 명령에 있을 수 있습니다.

trap 문 본문에서 실행된 최종 문이 continue(§8.5.2)인 경우, 오류 객체를 오류 스트림에 기록하는 작업이 억제되고, 예외를 발생시킨 트랩 문이 포함된 범위 안에서의 그 다음에 오는 명령문부터 실행이 계속됩니다. trap 문 본문(body)에서 실행된 최종 문이 break 문(§8.5.1)인 경우, 오류 개체를 오류 스트림에 쓰는 작업이 억제되고 예외가 다시 던져집니다.

trap 문 내에서 변수 $_ 현재 오류에 대한 설명을 포함합니다.

try 블록 내에서 발생한 예외에 일치하는 catch 블록이 없지만 일치하는 trap 문이 더 높은 블록 수준에 있는 경우를 고려합니다. try 블록의 finally 절이 실행된 후, 부모 범위에 일치하는 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}

다음 예제에서는 트랩 및 예외 생성 문장이 서로 다른 범위에 있습니다. 예외가 포착되어 처리된 후, 파이프라인에 1이 아닌 2를 쓰면서 실행이 다시 시작됩니다.

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

묘사:

데이터 문은 데이터 섹션을 만들어, 해당 섹션의 데이터를 코드와 분리합니다. 이 분리는 오류 메시지 및 도움말 문자열과 같은 텍스트에 대한 별도의 문자열 리소스 파일과 같은 기능을 지원합니다. 또한 다른 언어로 번역될 문자열을 보다 쉽게 격리, 찾기 및 처리할 수 있도록 하여 국제화를 지원하는 데 도움이 됩니다.

스크립트 또는 함수에는 0개 이상의 데이터 섹션이 있을 수 있습니다.

데이터 섹션의 문 블록 다음 PowerShell 기능만 포함하도록 제한됩니다.

  • -match 제외한 모든 연산자
  • if 선언문
  • 자동 변수는 $PSCulture, $PSUICulture, $true, $false$null.
  • 코멘트
  • 파이프라인
  • 세미콜론(;)으로 구분된 문장
  • 리터럴
  • ConvertFrom-StringData cmdlet에 대한 호출입니다.
  • SupportedCommand 매개 변수를 통해 식별된 다른 cmdlet

ConvertFrom-StringData cmdlet을 사용하는 경우 모든 형식의 문자열 리터럴을 사용하여 키/값 쌍을 표현할 수 있습니다. 그러나 expandable-string-literalexpandable-here-string-literal에는 변수 대체나 하위 식 확장이 포함되어서는 안 됩니다.

예제:

SupportedCommand 매개 변수는 지정된 cmdlet 또는 함수가 데이터만 생성한다는 것을 나타냅니다. 예를 들어 다음 데이터 섹션에는 XML 파일의 데이터 형식을 지정하는 ConvertTo-Xml사용자가 작성한 cmdlet이 포함되어 있습니다.

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

묘사:

함수 정의 정의되는 함수, 필터 또는 워크플로의 이름과 매개 변수의 이름(있는 경우)을 지정합니다. 또한 해당 함수의 목적을 달성하기 위해 실행되는 0개 이상의 문이 포함되어 있습니다.

각 함수는 클래스 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] 형식 제약 조건

매개 변수가 [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으로 표시된 블록)의 문들이 한 번 실행됩니다.

프로세스 블록 문(즉, 키워드 프로세스로 표시된 문)은 전달된 각 파이프라인 개체에 대해 실행됩니다. ($_ 파이프라인에서 들어오는 입력 컬렉션에서 처리되는 현재 개체에 대한 액세스를 제공합니다.) 즉, 0개 요소의 컬렉션이 파이프라인을 통해 전송되면 프로세스 블록이 전혀 실행되지 않습니다. 그러나 스크립트 또는 함수가 파이프라인 컨텍스트 외부에서 호출되는 경우, 이 블록은 정확히 한 번 실행되며, 현재 컬렉션 개체가 없으므로 $_$null로 설정됩니다.

엔드 블록(즉, 키워드 끝으로 표시된 문)의 문은 마지막 파이프라인 개체가 전달된 후 한 번 실행됩니다.

8.10.8 dynamicparam 블록

지금까지 §8.10의 하위 섹션은 소스 코드의 일부로서 정의된 정적 매개 변수를다루고 있습니다. 동적 매개변수 키워드로 표시된 dynamicparam 블록을 통해 정의할 수 있으며, 이는 명명된 블록의 또 다른 형태입니다 (dynamicparam). 이 기계의 대부분은 구현이 정의되어 있습니다.

동적 매개 변수는 특정 조건에서만 사용할 수 있는 cmdlet, 함수, 필터 또는 스크립트의 매개 변수입니다. 이러한 경우 중 하나는 cmdlet의 Set-Item 매개 변수입니다.

문장 블록에서는 if 문을 사용하여 함수에서 매개 변수를 사용할 수 있는 조건을 지정합니다. New-Object cmdlet을 사용하여 매개 변수를 나타내는 구현 정의 형식의 개체를 만들고 해당 이름을 지정합니다. 또한 New-Object 사용하여 매개 변수의 구현 정의 특성을 나타내는 다른 구현 정의 형식의 개체를 만듭니다.

다음 예제에서는 Name 및 Path라는 표준 매개 변수가 있는 함수와 DP1명명된 선택적 동적 매개 변수를 보여 줍니다. DP1 매개 변수는 PSet1 매개 변수 집합에 있으며 Int32형식입니다. DP1 매개 변수는 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.

매개 변수의 구현 정의 특성에는 필수, 위치ValueFromPipeline포함됩니다.

8.10.9 매개 변수 블록

매개 변수 블록 매개 변수를 선언하는 다른 방법을 제공합니다. 예를 들어 다음 매개 변수 선언 집합은 동일합니다.

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

매개 변수 블록특성 목록을 허용하는 반면, function-parameter-declaration은 허용하지 않습니다.

스크립트에는 매개 변수 블록 이 있을 수 있지만 함수 매개변수 선언은 있을 수 없습니다. 함수 또는 필터 정의에는 함수 매개 변수 선언 또는 매개 변수 블록있을 수 있지만 둘 다 있을 수는 없습니다.

다음 예제를 고려하세요.

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

하나의 매개 변수인 $ComputerNamestring[]형식을 가지며, 필수 항목이며, 파이프라인에서 입력을 받습니다.

매개 변수 특성에 대한 자세한 내용은 §12.3.7 참조하세요.

8.11 병렬 명령문

구문:

parallel-statement:
    *parallel* statement-block

병렬 문은 구현에서 정의된 방식으로 실행되는 0개 이상의 문을 포함합니다.

병렬 문은 워크플로(§8.10.2) 내에서만 허용됩니다.

8.12 순서 문장

구문:

sequence-statement:
    *sequence* statement-block

시퀀스 구문에는 구현에서 정의된 방식으로 실행되는 0개 이상의 명령문이 포함되어 있습니다.

시퀀스 문은 워크플로(§8.10.2)에서만 허용됩니다.

8.13 인라인스크립트 문

구문:

inlinescript-statement:
    inlinescript statement-block

inlinescript 문에는 구현에서 정의된 방식으로 실행되는 0개 이상의 문이 포함되어 있습니다.

inlinescript 문은 워크플로(§8.10.2)에서만 허용됩니다.

8.14 매개 변수 바인딩

스크립트, 함수, 필터 또는 cmdlet이 호출되면 각 인수를 위치별로 해당 매개 변수에 바인딩할 수 있으며 첫 번째 매개 변수는 위치가 0입니다.

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

스크립트, 함수, 필터 또는 cmdlet이 호출되면 인수를 이름으로 해당 매개 변수에 바인딩할 수 있습니다. 이 작업은 인수이 있는 매개변수를 사용하여 수행됩니다. 여기서 인수는 대시(-)로 시작하는 매개변수 이름과 해당 인수에 대한 값을 나타냅니다. 사용되는 매개 변수 이름에는 대/소문자를 구분하지 않는 맞춤법이 있을 수 있으며 해당 매개 변수를 고유하게 지정하는 접두사를 사용할 수 있습니다. 매개 변수 이름을 선택할 때는공통 매개 변수의 이름을 사용하지 마십시오.

함수 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을 참조하세요.

스크립트, 함수, 필터 또는 cmdlet은 호출 명령줄, 파이프라인 또는 둘 다에서 인수를 수신할 수 있습니다. 매개 변수 바인딩을 확인하기 위한 순서대로 단계는 다음과 같습니다.

  1. 명명된 모든 매개 변수를 바인딩한 다음,
  2. 위치 매개 변수를 바인딩한 다음
  3. 정확히 일치하는 값(§12.3.7)을 사용하여 파이프라인에서 바인딩합니다.
  4. 값을 사용하여 파이프라인에서 바인드한 후 변환합니다 (§12.3.7).
  5. 정확히 일치하는 이름으로 파이프라인에서 바인딩한 후에 (§12.3.7)
  6. 이름(§12.3.7)을 기준으로 변환을 사용하여 파이프라인에서 바인딩

이러한 단계 중 일부는 §6에 설명된 대로 변환을 포함합니다. 그러나 바인딩에 사용되는 변환 집합은 언어 변환에 사용된 것과 정확히 다릅니다. 특히

  • $null 값을 bool로 캐스팅할 수 있지만 $nullbool바인딩할 수 없습니다.
  • $null 이 cmdlet의 매개 변수에 전달 [switch] 되면 전달된 것처럼 $true 처리됩니다. 그러나 함수의 매개 변수에 [switch] 전달되면 전달된 것처럼 $false 처리됩니다.
  • 부울 또는 스위치 형식의 매개 변수는 숫자 또는 부울 인수에만 바인딩할 수 있습니다.
  • 매개 변수 형식이 컬렉션이 아니지만 인수가 일종의 컬렉션인 경우 매개 변수 형식이 개체 또는 PsObject가 아니면 변환이 시도되지 않습니다. (이 제한의 요점은 컬렉션을 문자열 매개 변수로 변환하는 것을 허용하지 않는 것입니다.) 그렇지 않으면 일반적인 변환이 시도됩니다.

매개 변수 형식이 IList 또는 ICollection<T>경우 생성자, op_Implicit 및 op_Explicit 통한 변환만 시도됩니다. 이러한 변환이 없으면 IList, ICollection<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"