Powershell Cmdlet, Function을 이용 하다 보면 명령 뒤의 Parameter를 필수 적으로 입력을 요구 할 때가 있다. 또 명령어 뒤에 -[parameter명] 을 붙히지 않고 공백으로 구분하여 입력 하면 자동으로 순서대로 Parameter를 인식 하는데 이런 동작들은 Cmdlet, Function 내부에 진입 하기 전에 Parameter Attribute 에 의해서 조절 된다.
즉 꼭 필요로 하는 Parameter를 Cmdlet 안에서 $null 체크를 하는 것이 아니라 (할 수도 있겠지만), Parameter Attribute 에 의해서 값이 체크 되고 통과 하지 않으면 자동으로 Parameter를 물어 본다.
예를 들어
Set-ExecutionPolicy
를 입력 하면 다음과 같이 ExecutionPolicy 를 물어 볼 것이다.
PS D:myScripts> Set-ExecutionPolicy cmdlet Set-ExecutionPolicy(명령 파이프라인 위치 1) 다음 매개 변수에 대한 값을 제공하십시오. ExecutionPolicy:
물론 당연하게 느껴 진다. 실행 정책(Execution Policy)을 설정(Set) 한다고 했는데 어떤 값으로 Set 할지 알려 주지 않았기 때문에 당연히 Cmdlet 이 ExecutionPolicy 값을 요구 한다.
이것은 Set-ExecutionPolicy Cmdlet 내부 Process 에 정의 되어 있는 것이 아니고 Parameter Attribute 에 의해서 체크 되고 또 입력이 요구 되는 것이다.
예제로 간단한 스크립트를 작정하면서 어떻게 Parameter Attribute를 사용 하는지 알아 보자.
다음은 입력한 이름과 일치하는 파일 또는 디렉토리를 찾는 스크립트 Search-Item.ps1 이다.
param ($Name) Get-ChildItem -Include $Name -Recurse
스크립트를 실행 해 보자. 만약 스크립트를 실행하는 현재 위치, 또는 하위 디렉토리에 test 라는 파일이 있다면 다음과 같이 검색 할 수 있다.
.Search-Item.ps1 -Name test
test 라는 파일이 존재 하지 않으면 아무 결과도 볼 수 없을 것이고 있다면 다음과 비슷한 결과를 볼 수 있을 것이다.
Mode LastWriteTime Length Name ---- ------------- ------ ---- d---- 2010-03-24 오후 3:27 test
이번엔 Parameter로 아무 것도 입력 하지 않고 스크립트를 실행 해 보자.
.Search-Item.ps1
아마도 현재 위치를 포함한 하위의 모든 파일, 디렉토리가 나올 것이다. 분명 잘 못된 동작이다.
그렇다면 Search-Item.ps1 의 -Name Parameter를 강제로 입력 하도록 하는것이 해결 방법중 하나가 되겠다. 이 때 Parameter Attribute를 유용하게 쓸 수 있다.
Search-Item.ps1을 다음과 같이 고쳐 보자.
param ([Parameter(Mandatory=$true)]$Name) Get-ChildItem -Include $Name -Recurse
Mandatory (필수) Property를 true 로 설정 했다. 즉 $Name Parameter는 필수로 입력 해야 된다는 이야기 이다. 물론 $false로 설정하면 반대의 효과이다.
그리고 또 다시 Parameter를 입력하지 않고 스크립트를 실행 시키면, 의도 대로 Parameter를 요구 한다.
PS D:myScripts> .Search-Item.ps1 cmdlet Search-Item.ps1(명령 파이프라인 위치 1) 다음 매개 변수에 대한 값을 제공하십시오. Name:
Parameter Attribute 에는 Mandatory 이외에도 몇가지 Property가 더 있는데 다음 링크를 참고 한다.
MSDN – ParamerterAttribute Properties
내가 즐겨 쓰는 Property 로는
HelpMessage
: 파라메터 설명 넣기
Mandatory
: 필수 Parameter
Position
: Parameter 이름을 명시 하지 않을 때 (-Name 과 같은.) Parameter의 위치
ValueFromPipeline
: true로 하면 Pipeline로 받은 값을 해당 Parameter의 입력으로 넣을 수 있다.
이 옵션들을 적당히 사용했을 때 Search-Item.ps1은 다음과 같다.
Search-Item.ps1
param ( [Parameter( HelpMessage="Item Name", Mandatory=$true, Position=0, ValueFromPipeline=$true )] $Name, [Parameter( HelpMessage="Base Path", Position=1 )] $BasePath = $(Get-Location) ) Get-ChildItem -Path $BasePath -Include $Name -Recurse