모든 PowerShell 명령에는 하나 이상의 매개변수, 종종 인수라고도 불리는 것이 있을 수 있습니다. PowerShell 함수에서 PowerShell 매개변수를 사용하지 않는다면, 좋은 PowerShell 코드를 작성하지 않은 것입니다!
이 기사에서는 PowerShell 매개변수 또는 인수를 생성하고 사용하는 방법의 거의 모든 측면을 배우게 될 것입니다!
이것은 제 책 ‘SysAdmins를 위한 PowerShell’에서의 샘플입니다. PowerShell을 배우거나 전문 기술을 익히고 싶다면, 확인해보세요!
매개변수가 필요한 이유는 무엇인가요?
함수를 생성하기 시작하면 매개변수를 포함할지 여부와 해당 매개변수가 작동하는 방식을 선택할 수 있습니다.
예를 들어, Microsoft Office를 설치하는 함수가 있다고 가정해 보겠습니다. 아마도 이 함수 내에서 Office 설치 프로그램을 음성 없이 호출할 것입니다. 함수가 하는 일은 우리의 목적에 관계가 없습니다. 함수의 기본 모양은 다음과 같습니다. 함수 이름과 스크립트 블록이 포함되어 있습니다.
이 예제에서는 매개변수 없이 Install-Office
를 실행했고, 그냥 작업을 수행했습니다.
Install-Office
함수에 매개변수가 있는지 여부는 중요하지 않았습니다. 아마도 필수적인 매개변수가 없었을 것입니다. 그렇지 않으면 PowerShell은 매개변수를 사용하지 않고 실행할 수 없었을 것입니다.
PowerShell 매개변수를 사용할 때는 언제인가요?
Office에는 많은 다른 버전이 있습니다. 아마도 Office 2013과 2016을 설치해야 할 것입니다. 현재는 이를 지정할 수 있는 방법이 없습니다. 동작을 변경하려면 매번 함수의 코드를 변경해야 합니다.
예를 들어, 서로 다른 버전을 설치하기 위해 두 개의 별도 함수를 만들 수 있습니다.
이렇게 하는 것도 가능하지만 확장 가능하지는 않습니다. Office의 각 버전마다 별도의 함수를 만들어야 합니다. 불필요하게 많은 코드를 중복해서 작성해야 합니다.
대신, 함수의 동작을 변경하기 위해 실행 시간에 다른 값을 전달할 수 있는 방법이 필요합니다. 이를 어떻게 할 수 있을까요?
예, 매개변수 또는 일부 사람들이 인자라고 부르는 것입니다.
코드를 매번 변경하지 않고도 Office의 다른 버전을 설치하고 싶기 때문에, 이 함수에 적어도 하나의 매개변수를 추가해야 합니다.
빠르게 PowerShell 매개변수를 떠올리기 전에, 먼저 스스로에게 질문해야 합니다. “이 함수에서 어떤 최소한의 변경이 필요할 것으로 예상하나요?”.
이 함수 내의 코드를 변경하지 않고 이 함수를 다시 실행해야 한다는 것을 기억하세요. 이 예에서는 매개변수가 명확할 것입니다. Version
매개변수를 추가해야 합니다. 하지만 코드가 수십 줄인 함수의 경우, 정답은 너무 명확하지 않을 수 있습니다. 가능한 한 정확하게 그 질문에 대답하는 것은 항상 도움이 됩니다.
따라서 Version
매개변수가 필요하다는 것을 알게 되었습니다. 이제 어떻게 추가할까요? 매우 훌륭한 프로그래밍 언어와 마찬가지로, 이를 구현하는 여러 가지 방법이 있습니다.
이 튜토리얼에서는 PowerShell을 사용하여 매개 변수를 만드는 “최상의” 방법을 보여 드리겠습니다. 그러나 이것이 유일한 매개 변수를 만드는 방법은 아닙니다.
위치 매개 변수라는 것이 있습니다. 이러한 매개 변수를 사용하면 매개 변수 이름을 지정하지 않고 매개 변수에 값을 전달할 수 있습니다. 위치 매개 변수는 작동하지만 “최상의 사례”로 간주되지 않습니다. 왜냐하면 매개 변수를 정의한 함수에 많은 매개 변수가 정의되어 있는 경우 특히 읽기 어렵기 때문입니다.
간단한 PowerShell 매개 변수 만들기
함수에 매개 변수를 만들려면 두 가지 주요 구성 요소가 필요합니다. param 블록과 매개 변수 자체입니다. param 블록은 param
키워드 다음에 괄호 집합으로 정의됩니다.
이 시점에서 함수의 실제 기능은 전혀 변경되지 않았습니다. 우리는 그저 몇 가지 배관을 조립하여 첫 번째 매개 변수에 대비하기 위해 준비를 마친 것입니다.
param 블록을 준비한 후에는 이제 매개 변수를 만들 수 있습니다. 제안하는 매개 변수 생성 방법은 Parameter
블록 다음에 매개 변수의 유형이 오고 그 아래에 매개 변수 변수 이름이 옵니다.
이제 PowerShell에서 함수 매개 변수를 만들었지만 여기에서 정확히 무슨 일이 발생했는지 알아볼까요?
Parameter
블록은 모든 매개 변수의 선택적이지만 권장되는 부분입니다. param 블록과 마찬가지로 이것은 매개 변수를 추가 기능을 추가할 준비를 하는 “함수 배관”입니다. 두 번째 줄은 매개 변수의 유형을 정의하는 곳입니다.
이 경우에는 버전 매개변수를 문자열로 변환하도록 선택했습니다. 명시적인 타입을 정의하는 것은 이 매개변수에 전달되는 모든 값이 이미 문자열이 아닌 경우 “변환”되도록 합니다.
이 타입은 필수는 아니지만 권장됩니다. 매개변수의 타입을 명시적으로 정의하는 것은 앞으로 발생할 수 있는 많은 원치 않는 상황을 크게 줄일 것입니다. 믿어요.
이제 매개변수를 정의했으니 Version
매개변수를 사용하여 버전 문자열을 전달하면 Install-Office
명령을 실행할 수 있습니다. 2013과 같이 Version
매개변수에 전달된 값은 매개변수의 인수 또는 값이라고 할 수 있습니다.
여기에서 무슨 일이 벌어지고 있나요? 2013 버전을 설치하고 싶다고 말했지만 여전히 2016이 설치되었다는 것을 알려줍니다. 매개변수를 추가하면 함수의 코드를 변수로 변경해야하는 것을 기억해야 합니다. 매개변수가 함수에 전달되면 해당 변수는 전달된 값이 무엇이든지로 확장됩니다.
2016이라는 정적 텍스트를 Version
매개변수 변수로 변경하고 단일 인용부호를 이중 인용부호로 변환하여 변수가 확장되도록 변경하세요.
이제 Version
매개변수에 전달하는 어떤 값이든 함수로 전달되어 $Version
변수로 사용됨을 확인할 수 있습니다.
필수 매개변수 속성
앞서 언급한 것처럼 [Parameter()]
라인은 단지 “함수 배관”이었고 함수를 추가 작업에 필요한 상태로 만들어야 하는 것을 말한 적이 있습니다. 매개변수에 매개변수 속성을 추가하는 것이 바로 이전에 언급한 추가 작업입니다.
A parameter doesn’t have to be a placeholder for a variable. PowerShell has a concept called parameter attributes and parameter validation. Parameter attributes change the behavior of the parameter in a lot of different ways.
예를 들어, 설정할 가장 일반적인 매개변수 속성 중 하나는 Mandatory
키워드입니다. 기본적으로 Version
매개변수를 사용하지 않고 Install-Office
함수를 호출할 수 있으며 정상적으로 실행됩니다. Version 매개변수는 선택 사항입니다. 물론, 함수 내부에서 $Version 변수를 확장하지 않을 것이므로 값을 지정하지 않았을 때는 실행되지 않을 것입니다. 그러나 여전히 실행됩니다.
매개변수를 만들 때 많은 경우에 사용자가 항상 해당 매개변수를 사용하도록 하고 싶을 것입니다. 함수의 코드 내에서 매개변수의 값에 의존하고, 매개변수가 전달되지 않으면 함수가 실패할 것입니다. 이러한 경우에는 사용자에게 이 매개변수 값을 함수에 전달하도록 강제하고 싶습니다. 이 매개변수가 필수가 되도록 하려는 것입니다.
매개변수를 사용자에게 강제로 사용하게 만드는 것은 여기에 구축된 기본 프레임워크가 있으면 간단합니다. 매개변수의 괄호 안에 Mandatory
키워드를 포함해야 합니다. 이를 설정한 후에는 매개변수 없이 함수를 실행하면 값을 입력할 때까지 실행이 중지됩니다.
함수는 Version
매개변수에 값을 지정할 때까지 기다립니다. 값을 지정하고 Enter를 누르면 PowerShell이 함수를 실행하고 다음으로 넘어갑니다. 매개변수에 값을 제공하면 PowerShell이 매번 매개변수를 사용자에게 묻지 않습니다.
PowerShell 매개변수 유효성 검사 속성
매개변수를 필수로 지정하는 것은 매우 일반적인 매개변수 속성 중 하나입니다. 그러나 매개변수 유효성 검사 속성을 사용할 수도 있습니다. 프로그래밍에서는 항상 사용자 입력을 가능한 한 제한하는 것이 중요합니다. 함수나 스크립트에 전달할 수 있는 정보를 제한함으로써 함수 내부에서 여러 가지 상황을 대비하기 위해 작성해야 하는 불필요한 코드를 제거할 수 있습니다.
예시를 통해 배우기
예를 들어, Install-Office
함수에서는 값을 2013
으로 전달하여 작동하는지를 보여줬습니다. 그래서 제가 코드를 작성했으니까요! 저는 다른 사람들이 2013이나 2016 버전을 지정할 것이라는 것이 당연하다고 가정합니다(코드에서는 이렇게 하지 마세요!). 하지만 여러분에게는 당연한 것이라도 다른 사람들에게는 그렇지 않을 수 있습니다.
버전에 대해 기술적인 것을 얘기하자면, 만약 Microsoft가 이전에 사용한 버전 스키마를 계속 사용한다면 2013 버전을 15.0
으로 지정하는 것이 더 정확할 것입니다. 그리고 2016 버전은 16.0
으로 지정할 것입니다. 하지만 여러분이 그들이 2013이나 2016 버전을 지정할 것이라고 가정한다면, 그 버전이 포함된 폴더를 찾거나 다른 작업을 하는 함수 내부에 있는 코드가 있을 수도 있습니다.
아래 예시에서는 $Version
문자열을 파일 경로에 사용하는 경우입니다. 만약 다른 사람이 Office2013
이나 Office2016
의 폴더 이름을 완성하지 못하는 값을 전달한다면, 해당 코드는 실패하거나 예상치 못한 폴더를 삭제하거나 계획하지 않은 변경을 가할 수도 있습니다.
사용자가 입력할 것으로 예상하는 내용을 제한하기 위해 PowerShell 매개변수 유효성 검사를 추가할 수 있습니다.
ValidateSet 매개변수 유효성 검사 속성 사용
사용할 수 있는 다양한 종류의 매개변수 유효성 검사가 있습니다. 전체 목록을 확인하려면 Get-Help about_Functions_Advanced_Parameters
를 실행하세요. 이 예제에서는 ValidateSet
속성이 가장 적합할 것입니다.
ValidateSet
유효성 검사 속성을 사용하면 매개변수 값으로 허용되는 값 목록을 지정할 수 있습니다. 여기서는 문자열 2013 또는 2016만 고려하므로 사용자가 이러한 값만 지정할 수 있도록 보장하고자 합니다. 그렇지 않으면 함수가 즉시 실패하며, 실패 이유를 알려줍니다.
매개변수 유효성 검사 속성은 원래 Parameter
키워드 바로 아래에 추가할 수 있습니다. 이 예제에서는 매개변수 속성의 괄호 안에 항목 배열인 2013과 2016이 있습니다. 매개변수 유효성 검사 속성은 PowerShell에게 Version
에 유효한 값은 2013 또는 2016뿐이라고 알려줍니다. 집합에 있는 것 이외의 값을 전달하려고 하면, 특정 옵션만 사용할 수 있다는 알림이 포함된 오류 메시지를 받게 됩니다.
ValidateSet
속성은 일반적으로 사용되는 유효성 검사 속성입니다. 매개 변수 값이 제한될 수 있는 모든 방법에 대한 자세한 내용은 Functions_Advanced_Parameters
도움말 주제를 실행하여 확인하십시오. Get-Help about_Functions_Advanced_Parameters
.
매개 변수 집합
특정 PowerShell 매개 변수를 다른 매개 변수와 함께만 사용하려면 어떻게 해야 할까요? Install-Office
함수에 Path
매개 변수를 추가했다고 가정해 보겠습니다. 이 경로는 설치 프로그램의 버전을 설치합니다. 이 경우에는 사용자가 Version
매개 변수를 사용하지 않도록 하려고 합니다.
매개 변수 집합이 필요합니다.
매개 변수를 그룹으로 묶어서 동일한 집합 내의 다른 매개 변수와만 함께 사용할 수 있습니다. 아래의 함수를 사용하여 이제 Version
매개 변수와 Path
매개 변수를 함께 사용하여 설치 프로그램의 경로를 찾을 수 있습니다.
그러나 이는 문제가 발생합니다. 사용자는 둘 다 매개 변수를 사용할 수 있습니다. 게다가 두 매개 변수가 필수이므로 사용자는 원하지 않는 경우에도 두 매개 변수를 사용해야 합니다. 이를 해결하기 위해 각 매개 변수를 아래와 같이 매개 변수 집합에 배치할 수 있습니다.
각 매개 변수에 매개 변수 집합 이름을 정의함으로써 그룹을 제어할 수 있습니다.
기본 매개 변수 집합
사용자가 매개 변수 없이 Install-Office
를 실행하려고 할 때 어떻게 처리해야 할까요? 이것은 고려되지 않은 상황이며, 친절한 오류 메시지가 표시됩니다.

이를 수정하려면 CmdletBinding()
영역 내에서 기본 매개변수 집합을 정의해야 합니다. 이렇게 하면 매개변수가 명시적으로 사용되지 않은 경우 함수가 사용할 매개변수 집합을 선택하도록 지정합니다. [CmdletBinding()]
을 [CmdletBinding(DefaultParameterSetName = 'ByVersion')]
로 변경하세요.
이제 Install-Office
를 실행할 때, 매개변수 집합을 사용하므로 Version
매개변수에 대해 프롬프트가 표시됩니다.
파이프라인 입력
지금까지의 예제에서는 PowerShell 매개변수를 사용하여 전형적인 -ParameterName Value 구문을 사용하여 함수를 생성했습니다. 그러나 이미 알게 된 대로 PowerShell은 직관적인 파이프라인을 제공하여 “전형적인” 구문을 사용하지 않고도 개체를 한 명령에서 다른 명령으로 원활하게 전달할 수 있습니다.
파이프라인을 사용하면 |
파이프 심볼을 사용하여 명령을 “체인”하여 사용자가 Get-Service
의 출력을 Start-Service
로 전달할 수 있도록 하여 Name
매개변수를 Start-Service
로 전달하는 단축키를 제공합니다.
루프를 사용한 “옛날” 방법
작업 중인 사용자 정의 함수에서 Office를 설치하고 Version
매개변수가 있습니다. 예를 들어 각 컴퓨터 옆에 설치해야 하는 Office 버전이 있는 CSV 파일의 컴퓨터 이름 목록이 있다고 가정해 보겠습니다. CSV 파일은 다음과 같습니다:
각 컴퓨터 옆에 있는 Office 버전을 해당 컴퓨터에 설치하려고 합니다.
먼저 함수에 ComputerName
매개변수를 추가해야합니다. 각 함수 반복마다 다른 컴퓨터 이름을 전달하기 위해서입니다. 아래에는 가상의 함수에 포함될 수 있는 일부 코드를 의사 코드로 작성하고 변수가 함수 내에서 어떻게 전개되는지 확인하기 위해 Write-Host
를 추가했습니다.
함수에 ComputerName
매개변수를 추가한 후, CSV 파일을 읽고 컴퓨터 이름과 버전 값을 Install-Office
함수에 전달하는 방법을 사용할 수 있습니다.
매개변수에 대한 파이프라인 입력 빌드
CSV 행을 읽고 각 행의 속성을 함수에 전달하기 위해 루프를 사용하는 방식은 “옛날” 방식입니다. 이 섹션에서는 foreach
루프를 완전히 사용하지 않고 대신 파이프라인을 사용하려고 합니다.
현재 함수는 파이프라인을 전혀 지원하지 않습니다. 컴퓨터 이름과 버전을 각각의 함수에 파이프라인을 사용하여 전달할 수 있다고 가정하는 것이 직관적으로 이해되지만, 아래 코드를 보면 CSV를 읽고 직접 Install-Office
에 전달하지만 이는 작동하지 않습니다.
당신은 원하는 대로 가정할 수 있지만, 그렇게 해서는 작동하지 않습니다. 우리는 Import-Csv
가 객체 속성으로 보내는 Version
매개변수를 입력하라는 메시지를 받습니다. 왜 작동하지 않는 걸까요? 아직 파이프라인 지원을 추가하지 않았기 때문입니다.
PowerShell 함수에는 두 가지 종류의 파이프라인 입력이 있습니다. ByValue (전체 객체)와 ByPropertyName (단일 객체 속성)입니다. Import-Csv
의 출력을 Install-Office
의 입력과 어떻게 연결하는 것이 최선인지 생각해보세요.
전혀 리팩토링하지 않고도, ByPropertyName
방법을 사용할 수 있습니다. 왜냐하면 Import-Csv
가 이미 CSV의 열로서 Version
과 ComputerName
속성을 반환하기 때문입니다.
사용자 정의 함수에 파이프라인 지원을 추가하는 것은 생각보다 훨씬 간단합니다. 하나의 키워드로 표시되는 매개변수 특성만 추가하면 됩니다. ValueFromPipeline
또는 ValueFromPipelineByPropertyName
중 하나를 사용하면 됩니다.
이 예제에서는 Import-Csv
에서 반환된 ComputerName
과 Version
속성을 Install-Office
의 Version
과 ComputerName
매개변수에 바인딩하려고 하므로, ValueFromPipelineByPropertyName
을 사용할 것입니다.
이러한 매개변수를 모두 바인딩하려면 아래에 표시된 대로 두 매개변수에 이 키워드를 추가하고 파이프라인을 사용하여 함수를 다시 실행하면 됩니다.
이상하네요. CSV의 마지막 행만 실행되었습니다. 무슨 일이 벌어지고 있는 걸까요? 파이프라인 지원 없이 함수를 빌드할 때는 필요하지 않은 개념을 건너뛰었기 때문에 마지막 행에 대해서만 함수를 실행한 것입니다.
Process 블록을 잊지 마세요!
파이프라인 지원이 필요한 함수를 생성해야 할 때는, 함수 내에 “임베디드” 블록인 process를 포함해야 합니다. 이 process 블록은 PowerShell에게 파이프라인 입력을 받을 때마다 함수를 실행하도록 지시합니다. 기본적으로 마지막 행만 실행됩니다.
기술적으로는 begin과 end와 같은 다른 블록도 추가할 수 있지만, 스크립터들은 그렇게 자주 사용하지 않습니다.
PowerShell에게 이 함수를 들어오는 각 객체에 대해 실행하도록 지시하려면, 해당 코드가 포함된 process 블록을 추가하겠습니다.
이제 각 개체의 Version
및 ComputerName
속성이 Import-Csv
에서 반환되어 Install-Office
에 전달되고 Version
및 ComputerName
매개변수에 바인딩되었습니다.
자원
함수 매개변수 작동 방식에 대해 자세히 알아보려면 PowerShell 함수에 대한 블로그 포스트를 확인하세요.
I also encourage you to check my Pluralsight course entitled Building Advanced PowerShell Functions and Modules for an in-depth breakdown of everything there is to know about PowerShell functions, function parameters, and PowerShell modules.