about_Parameters_Default_Values

about_Parameters_Default_Values

도입

$PSDefaultParameterValues라는 이름의 기본 설정 변수 하나만 기억해 두면 되는데요, 이 변수에 값을 넣어 두면 cmdlet·고급 함수(advanced function)·스크립트의 매개변수 기본값을 원하는 대로 바꿔 쓸 수 있어요. 매번 똑같이 입력하기 번거로운 값, 그러니까 이메일 서버 이름이나 프로젝트 GUID처럼 기억하기 어려운 값을 한 번만 지정해 두면 명령줄에서 계속 생략해도 되죠.

이 변수는 기본값이 따로 없어서, 다음 세션에도 유지하고 싶다면 이 할당문을 여러분의 **PowerShell 프로필(profile)**에 추가해 두시면 됩니다. $PSDefaultParameterValuesPowerShell 3.0에서 처음 도입됐어요.

출처: about_Parameters_Default_Values (Microsoft Learn)

본문

핵심 규칙 잠깐 — 키와 값이 어떻게 생겼나

$PSDefaultParameterValuesSystem.Management.Automation.DefaultParameterDictionary 형식의 객체인데, 그냥 해시테이블에 키 형식을 검증하는 기능이 조금 더 붙은 거라고 생각하면 돼요. 키-값 쌍의 규칙은 이래요.

  • CommandName:ParameterName 형식이에요.
  • 은 그 매개변수의 기본값이거나, 기본값을 돌려주는 ScriptBlock이에요.

키에서 CommandName은 반드시 CmdletBinding 특성을 쓰는 cmdlet·고급 함수·스크립트 파일의 이름이어야 하고, 스크립트 이름은 (Get-Command -Name .\script.ps1).Name이 보고하는 이름과 일치해야 해요.

참고: PowerShell이 CommandName에 별칭(alias)을 지정하는 걸 막지는 않아요. 그런데 어떤 경우엔 정의가 무시되거나 오류가 나기도 하거든요. 되도록 명령 별칭에는 기본값을 정의하지 않는 것이 좋습니다.

은 매개변수와 호환되는 형식의 객체이거나, 그런 값을 돌려주는 ScriptBlock이에요. 값이 ScriptBlock이면 PowerShell이 그 스크립트블록을 평가해서 결과를 매개변수 값으로 써요. 그런데 매개변수가 ScriptBlock 형식을 기대하는 경우라면 이야기가 달라져요 — 값을 중괄호로 한 번 더 감싸야 합니다. 바깥 ScriptBlock을 평가한 결과가 안쪽 ScriptBlock이 되고, 그 안쪽 ScriptBlock이 새로운 기본 매개변수 값이 되는 거예요. 예:

$PSDefaultParameterValues = @{ 'Invoke-Command:ScriptBlock' = { { Get-Process } } }

값 추가·삭제는 Add()와 Remove()로

특정 키-값 쌍만 추가하거나 뺄 때는 Add()Remove() 메서드를 쓰면 돼요. 이렇게 하면 다른 기존 값들을 건드리지 않아요.

$PSDefaultParameterValues.Add('CmdletName:ParameterName', 'DefaultValue')
$PSDefaultParameterValues.Remove('CmdletName:ParameterName')

기존 키-값 쌍의 값을 바꿀 때는 인덱싱이나 멤버 접근을 쓰면 됩니다. 예:

$PSDefaultParameterValues.'CommandName:ParameterName' = 'DefaultValue2'
$PSDefaultParameterValues['CommandName:ParameterName'] = 'DefaultValue1'

$PSDefaultParameterValues에 값 지정하기

cmdlet 매개변수의 기본값을 정의하려면, 알맞은 키-값 쌍이 담긴 해시테이블을 $PSDefaultParameterValues 변수에 할당하면 돼요. 해시테이블에는 여러 키-값 쌍을 넣을 수 있고요. 이 예제는 Send-MailMessage:SmtpServerGet-WinEvent:LogName 키에 기본값을 설정해요.

$PSDefaultParameterValues = @{
  'Send-MailMessage:SmtpServer' = 'Server123'
  'Get-WinEvent:LogName' = 'Microsoft-Windows-PrintService/Operational'
}

cmdlet 이름과 매개변수 이름에는 와일드카드 문자를 쓸 수 있어요. 그리고 [switch] 계열 매개변수, 예를 들어 Verbose 같은 건 $true$false로 값을 정해요. 이 예제는 모든 명령에 대해 공용 매개변수 Verbose$true로 설정해요.

$PSDefaultParameterValues = @{ '*:Verbose' = $true }

매개변수가 여러 값을 받는 경우라면, 기본값도 배열로 여러 개 줄 수 있어요. 이 예제는 Invoke-Command:ComputerName 키의 기본값을 Server01, Server02라는 두 문자열로 이루어진 배열로 지정하죠.

$PSDefaultParameterValues = @{ 'Invoke-Command:ComputerName' = 'Server01', 'Server02' }

정의된 값 확인하기

이렇게 정의했다고 해볼게요.

$PSDefaultParameterValues = @{
  'Send-MailMessage:SmtpServer' = 'Server123'
  'Get-WinEvent:LogName' = 'Microsoft-Windows-PrintService/Operational'
  'Get-*:Verbose' = $true
}

정의된 값은 명령 프롬프트에서 $PSDefaultParameterValues만 입력하면 확인할 수 있어요.

PS> $PSDefaultParameterValues
Name                          Value
----                          -----
Get-WinEvent:LogName          Microsoft-Windows-PrintService/Operational
Get-*:Verbose                 True
Send-MailMessage:SmtpServer   Server123

특정 값 하나를 뽑고 싶다면 인덱싱이나 멤버 접근을 쓰면 되고요.

PS> $PSDefaultParameterValues['Send-MailMessage:SmtpServer']   # 인덱스 표기
Server123
PS> $PSDefaultParameterValues.'Get-*:Verbose'                  # 멤버 접근 표기
True

기본값을 조건에 따라 바꾸려면 ScriptBlock

조건에 따라 매개변수에 서로 다른 기본값을 주고 싶을 때 스크립트블록을 쓸 수 있어요. PowerShell이 스크립트블록을 평가하고, 그 결과를 기본 매개변수 값으로 사용한답니다.

Format-Table:AutoSize 키는 [switch] 매개변수를 기본값 $true로 설정하는데, if 문 안에 $Host.NameConsoleHost여야 한다는 조건이 들어 있어요.

$PSDefaultParameterValues = @{ 'Format-Table:AutoSize' = { if ($Host.Name -eq 'ConsoleHost') { $true } } }

매개변수가 ScriptBlock 값을 받는 경우에는, 그 ScriptBlock을 중괄호로 한 번 더 감싸야 한다는 것, 아까 말씀드렸죠? 바깥 ScriptBlock을 평가한 결과가 안쪽 ScriptBlock이 되고, 그 안쪽 ScriptBlock이 새로운 기본 매개변수 값이 됩니다.

$PSDefaultParameterValues = @{ 'Invoke-Command:ScriptBlock' = { { Get-EventLog -Log System } } }

기존 $PSDefaultParameterValues 변수에 값 추가하기

값을 추가할 때는 Add() 메서드를 쓰면 돼요. 추가한다고 해서 해시테이블에 이미 있던 값들이 영향을 받지는 않습니다. 사이는 쉼표(,)로 구분해 주세요.

$PSDefaultParameterValues.Add('Get-Process:Name', 'PowerShell')

그러면 아까의 해시테이블에 새 키-값 쌍이 하나 더 붙게 돼요.

PS> $PSDefaultParameterValues
Name                          Value
----                          -----
Get-Process:Name              PowerShell
Get-WinEvent:LogName          Microsoft-Windows-PrintService/Operational
Get-*:Verbose                 True
Send-MailMessage:SmtpServer   Server123

값 삭제하기

값을 뺄 때는 Remove() 메서드를 쓰면 돼요. 삭제한다고 해서 해시테이블에 이미 있던 값들이 영향을 받지 않아요. 이 예제는 바로 위에서 추가한 키-값 쌍을 제거한답니다.

PS> $PSDefaultParameterValues.Remove('Get-Process:Name')
PS> $PSDefaultParameterValues
Name                          Value
----                          -----
Get-WinEvent:LogName          Microsoft-Windows-PrintService/Operational
Get-*:Verbose                 True
Send-MailMessage:SmtpServer   Server123

값 바꾸기

기존 키-값 쌍의 기본값을 바꿀 때는 인덱싱이나 멤버 접근을 쓰면 됩니다. 이 예제에서는 Send-MailMessage:SmtpServer 키의 기본값을 새 값인 ServerXYZ로 변경해요.

PS> $PSDefaultParameterValues['Send-MailMessage:SmtpServer'] = 'ServerXYZ'
PS> $PSDefaultParameterValues
Name                          Value
----                          -----
Get-WinEvent:LogName          Microsoft-Windows-PrintService/Operational
Get-*:Verbose                 True
Send-MailMessage:SmtpServer   ServerXYZ

비활성화했다가 다시 활성화하기

$PSDefaultParameterValues임시로 비활성화했다가 다시 켤 수도 있어요. 서로 다른 기본 매개변수 값이 필요한 스크립트를 돌리고 있을 때 특히 유용하겠죠.

비활성화하려면 Disabled 키를 추가하고 값에 $true를 넣으면 돼요. 값들은 그대로 보존되지만, 더 이상 사용되지 않아요.

PS> $PSDefaultParameterValues.Add('Disabled', $true)
PS> $PSDefaultParameterValues
Name                          Value
----                          -----
Disabled                      True
Get-WinEvent:LogName          Microsoft-Windows-PrintService/Operational
Get-*:Verbose                 True
Send-MailMessage:SmtpServer   ServerXYZ

다시 활성화하려면 Disabled 키를 제거하거나, Disabled 키의 값을 $false로 바꾸면 됩니다.

PS> $PSDefaultParameterValues.Disabled = $false
PS> $PSDefaultParameterValues
Name                          Value
----                          -----
Disabled                      False
Get-WinEvent:LogName          Microsoft-Windows-PrintService/Operational
Get-*:Verbose                 True
Send-MailMessage:SmtpServer   ServerXYZ

더 알아보기