about_Functions_Advanced
about_Functions_Advanced
스크립트로 cmdlet을 만드는 방법인 고급 함수(advanced function)를 소개해 드릴게요.
본문
짧은 설명
고급 함수는 스크립트를 이용해 cmdlet을 만들 수 있게 해 주는 방법이에요.
자세한 설명
cmdlet은 PowerShell의 파이프라인 문법(의미 구조)에 참여하는 하나의 명령이에요. 여기에는 이진 cmdlet, PowerShell 고급 함수, CDXML cmdlet이 모두 포함돼요.
고급 함수를 쓰면 PowerShell 함수로 작성된 cmdlet을 만들 수 있어요. 이진 cmdlet을 직접 작성하고 컴파일하지 않아도 되니, cmdlet을 훨씬 쉽게 만들 수 있답니다. 이진 cmdlet은 C# 같은 .NET 언어로 작성되는 .NET 클래스예요.
고급 함수는 [CmdletBinding] 특성을 사용해서 함수가 cmdlet처럼 동작한다는 걸 표시해요. 이 [CmdletBinding] 특성은 컴파일된 cmdlet 클래스에서 해당 클래스를 cmdlet으로 식별할 때 쓰는 [Cmdlet] 특성과 비슷해요. 이 특성에 대한 자세한 내용은 about_Functions_CmdletBindingAttribute 문서를 참고해 주세요.
함수의 매개 변수는 param() 구문 안에 선언된 변수들이에요. [Parameter()] 특성을 단독으로 쓰거나, [Alias()] 특성 혹은 매개 변수 검증 특성들과 함께 쓸 수 있어요. 매개 변수를 선언하는 방법은 about_Functions_Advanced_Parameters 문서를 참고하세요.
아래 예시는 이름을 입력받아 그 이름으로 인사말을 출력하는 함수예요. 컴파일된 cmdlet의 '동사-명사' 쌍처럼 '동사(Send)'와 '명사(Greeting)'로 이루어진 이름을 가진 걸 볼 수 있어요. 다만 함수가 반드시 동사-명사 이름을 가져야 하는 건 아니에요.
function Send-Greeting
{
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)]
[string]$Name
)
process
{
Write-Host ("Hello " + $Name + "!")
}
}
이 함수는 작업을 process 블록에서 수행해요. 이는 컴파일된 cmdlet에서 쓰이는 ProcessingRecord 메서드와 같아요. process 블록과 그 밖의 명명된 블록들에 대한 설명은 about_Functions_Advanced_Methods 문서에 있어요.
고급 함수는 컴파일된 cmdlet과 다음과 같은 점에서 달라요.
- 고급 함수는 문자열 배열이 Boolean 매개 변수에 바인딩될 때 예외를 던지지 않아요.
- ValidateSet 특성과 ValidatePattern 특성은 명명된 매개 변수를 넘겨줄 수 없어요.
- 고급 함수는 트랜잭션(transaction)에서 사용할 수 없어요.
PIPELINESTOPTOKEN
PowerShell 7.6-preview.4부터 $PSCmdlet에 PipelineStopToken 속성이 추가됐어요. 이 속성은 PowerShell 중지 이벤트 소스에 연결된 CancellationToken에 접근할 수 있게 해 줘요. 이 토큰은 PowerShell 파이프라인이 중지 요청을 받으면 활성화(트리거)돼요. CancellationToken 오버로드를 받는 .NET 메서드에 이 토큰을 넘겨주면, 메서드가 끝날 때까지 기다리지 않고 요청 시점에 곧바로 메서드를 빠져나올 수 있어요.
다음 예시에서 함수는 HttpClient.GetStringAsync를 호출해요. 네트워크가 느리거나 반환되는 데이터가 많으면 응답이 오래 걸릴 수 있는 메서드예요.
function Invoke-CancelableWebRequest {
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)]
[string]
$Url
)
$client = [System.Net.Http.HttpClient]::new()
$client.GetStringAsync(
$Url,
$PSCmdlet.PipelineStopToken).GetAwaiter().GetResult()
}
Invoke-CancelableWebRequest -Url https://httpbin.org/delay/10
# Press ctrl+c to cancel