about_Requires — 스크립트 실행 전에 조건을 검사하는 #Requires

about_Requires — 스크립트 실행 전에 조건을 검사하는 #Requires

누군가 만든 스크립트나 모듈이 "이 PowerShell 버전에서만 돌아요", "이 모듈이 없으면 안 돼요" 같은 조건을 걸어두면, 그 조건을 만족하지 않은 환경에서는 스크립트가 아예 실행되지 않아요. 그걸 담당하는 게 바로 #Requires 문이에요. 이번엔 #Requires가 어떤 일을 하고, 어떻게 쓰는지 하나씩 살펴볼게요.

출처: about_Requires — Microsoft Learn

본문

이 문은 무엇을 하나요

#Requires 문은 필요한 요소가 갖춰져 있지 않으면 스크립트가 실행되지 않도록 막아요. 여기서 '필요한 요소'란 PowerShell 버전, 모듈(그리고 그 버전), 그리고 edition 같은 전제 조건을 말해요. 조건을 만족하지 않으면 PowerShell은 스크립트를 실행하지 않고, 탭 완성 같은 다른 런타임 기능도 제공하지 않아요.

문법

#Requires -Version <N>[.<n>]
#Requires -Modules { <Module-Name> | <Hashtable> }
#Requires -PSEdition <PSEdition-Name>
#Requires -RunAsAdministrator

문법을 더 자세히 보려면 ScriptRequirements 문서를 참고하세요.

사용 규칙

스크립트에는 #Requires 문을 여러 개 넣을 수 있고, 스크립트의 아무 줄에나 위치할 수 있어요.

한 가지 재미있는 점이 있는데요, #Requires 문을 함수 안에 넣어도 그 범위가 함수로 제한되지 않아요. 모든 #Requires 문은 항상 전역으로 적용되고, 스크립트가 실행되기 전에 반드시 충족되어야 해요.

주의할 점이 있어요. #Requires 문이 스크립트의 어느 줄에 있든, 그 위치는 적용되는 순서에 영향을 주지 않아요. 스크립트가 실행되기 전에 #Requires 문이 제시하는 전역 상태가 반드시 충족되어 있어야 해요.

예를 들어볼게요.

Get-Module AzureRM.Netcore | Remove-Module
#Requires -Modules AzureRM.Netcore

위 코드는 #Requires 문보다 앞에서 필요한 모듈을 제거하고 있으니 "이건 안 돌아야 하는 거 아닌가?"라고 생각할 수 있어요. 하지만 실제로는 그렇지 않아요. #Requires 문이 요구하는 상태는 스크립트가 실행되기 전에 충족되어 있어야 하고, 그다음에 스크립트 첫 줄이 그 상태를 무효화시킨 거거든요.

매개 변수

-Assembly <Assembly 경로> | <.NET 어셈블리 사양>

중요한 안내가 있어요. -Assembly 문법은 더 이상 사용되지 않아요(deprecated). 실제로 아무 기능도 하지 않는데요, PowerShell 5.1에서 문법만 추가되었고 뒷받침하는 코드는 구현된 적이 없어요. 그래도 하위 호환성을 위해 이 문법은 여전히 받아들여져요.

이 매개 변수는 어셈블리 DLL 파일의 경로나 .NET 어셈블리 이름을 지정해요. Assembly 매개 변수는 PowerShell 5.0에서 도입되었어요. .NET 어셈블리에 대한 자세한 내용은 Assembly names 문서를 참고하세요.

예를 들면 이렇게 써요.

#Requires -Assembly path\to\foo.dll
#Requires -Assembly "System.Management.Automation, Version=3.0.0.0,
  Culture=neutral, PublicKeyToken=31bf3856ad364e35"

-Version [.]

스크립트가 요구하는 최소한의 PowerShell 버전을 지정해요. 주 버전 번호와 선택적으로 부 버전 번호를 입력하면 돼요.

예를 들면 이렇게요.

#Requires -Version 6.0

-Modules <모듈 이름> | <해시 테이블>

스크립트가 요구하는 PowerShell 모듈을 지정해요. 모듈 이름과 선택적으로 버전 번호를 입력하면 돼요.

필요한 모듈이 현재 세션에 없으면 PowerShell이 그 모듈을 가져와요. 그런데 모듈을 가져올 수 없으면 PowerShell은 종료 오류(terminating error)를 던져요.

참고로 #Requires 문은 모듈 안의 클래스 정의와 열거형 정의는 불러오지 않아요. 클래스와 열거형 정의까지 포함해 모듈을 가져오려면 스크립트 맨 앞에 using module 문을 사용하세요. 자세한 내용은 about_Using 문서를 참고해요.

각 모듈에 대해 모듈 이름(<String>)이나 해시 테이블을 입력해요. 문자열과 해시 테이블을 섞어 쓸 수도 있어요. 해시 테이블은 다음 키를 가져요.

  • ModuleName - 필수. 모듈 이름을 지정해요.
  • GUID - 선택. 모듈의 GUID를 지정해요.
  • 아래 세 키 중 하나는 반드시 지정해야 해요.
  • ModuleVersion - 모듈의 허용 가능한 최소 버전을 지정해요.
  • MaximumVersion - 모듈의 허용 가능한 최대 버전을 지정해요.
  • RequiredVersion - 정확히 필요한 모듈 버전을 지정해요. 이 키는 다른 Version 키와 함께 쓸 수 없어요.

참고할 점이 있어요.

  • RequiredVersion은 Windows PowerShell 5.0에서 추가되었어요.
  • MaximumVersion은 Windows PowerShell 5.1에서 추가되었어요.

몇 가지 예시를 볼게요.

AzureRM.Netcore(버전 0.12.0 이상)가 설치되어 있어야 한다면:

#Requires -Modules @{ ModuleName="AzureRM.Netcore"; ModuleVersion="0.12.0" }

AzureRM.Netcore(정확히 버전 0.12.0만)이 설치되어 있어야 한다면:

#Requires -Modules @{ ModuleName="AzureRM.Netcore"; RequiredVersion="0.12.0" }

AzureRM.Netcore(버전 0.12.0 이하)가 설치되어 있어야 한다면:

#Requires -Modules @{ ModuleName="AzureRM.Netcore"; MaximumVersion="0.12.0" }

아무 버전의 AzureRM.NetcorePowerShellGet이 설치되어 있어야 한다면:

#Requires -Modules AzureRM.Netcore, PowerShellGet

RequiredVersion 키를 쓸 때는 버전 문자열이 요구하는 버전과 정확히 일치하는지 확인해야 해요.

Get-Module AzureRM.Netcore -ListAvailable
    Directory: /home/azureuser/.local/share/powershell/Modules

ModuleType Version Name            PSEdition ExportedCommands
---------- ------- ----            --------- ----------------
Script     0.12.0  AzureRM.Netcore Core

반면 다음 예시는 0.120.12.0과 정확히 일치하지 않기 때문에 실패해요.

#Requires -Modules @{ ModuleName="AzureRM.Netcore"; RequiredVersion="0.12" }

-PSEdition <PSEdition 이름>

스크립트가 요구하는 PowerShell edition을 지정해요. 유효한 값은 PowerShell용 Core와 Windows PowerShell용 Desktop이에요.

예를 들면 이렇게요.

#Requires -PSEdition Core

-RunAsAdministrator

[switch] 매개 변수를 #Requires 문에 추가하면, 스크립트를 실행하는 PowerShell 세션이 **상승된 사용자 권한(elevated user rights)**으로 시작되어야 한다는 뜻이 돼요. RunAsAdministrator 매개 변수는 Windows가 아닌 운영 체제에서는 무시되어요. 이 매개 변수는 PowerShell 4.0에서 도입되었어요.

예를 들면 이렇게요.

#Requires -RunAsAdministrator

예시

다음 스크립트에는 #Requires 문이 두 개 들어 있어요. 두 문에서 지정한 요구 사항이 모두 충족되지 않으면 스크립트는 실행되지 않아요. 각 #Requires 문은 줄의 첫 번째 항목이어야 해요.

#Requires -Modules AzureRM.Netcore
#Requires -Version 6.0
param
(
    [Parameter(Mandatory=$true)]
    [string[]]
    $Path
)
...

더 알아보기