PowerShell 함수에 자격 증명 지원 추가
참고 항목
현재 문서의 원본 버전은 @joshduffney가 작성한 블로그에 있습니다. 이 문서는 이 사이트에 포함하기 위해 편집되었습니다. PowerShell 팀은 이 콘텐츠를 공유해 주신 Josh에게 감사드립니다. duffney.io 자신의 블로그를 검사.
이 문서에서는 PowerShell 함수에 자격 증명 매개 변수를 추가하는 방법과 원하는 이유를 보여 줍니다. 자격 증명 매개 변수는 함수 또는 cmdlet을 다른 사용자로 실행할 수 있도록 하는 것입니다. 가장 일반적인 용도는 상승된 사용자 계정으로 함수 또는 cmdlet을 실행하는 것입니다.
예를 들어 cmdlet New-ADUser
에는 do기본 관리자 자격 증명을 제공하여 할 일기본 계정을 만들 수 있는 자격 증명 매개 변수가 있습니다. PowerShell 세션을 실행하는 일반 계정에 아직 이 액세스 권한이 없는 것으로 가정합니다.
자격 증명 개체 만들기
PSCredential 개체는 사용자 이름 및 암호와 같은 보안 자격 증명 집합을 나타냅니다. 해당 자격 증명 개체에서 사용자 계정으로 실행되는 함수에 매개 변수로 개체를 전달할 수 있습니다. 자격 증명 개체를 만들 수 있는 몇 가지 방법이 있습니다. 자격 증명 개체를 만드는 첫 번째 방법은 PowerShell cmdlet Get-Credential
을 사용하는 것입니다. 매개 변수 없이 실행하면 사용자 이름과 암호를 묻는 메시지가 표시됩니다. 또는 일부 선택적 매개 변수를 사용하여 cmdlet을 호출할 수 있습니다.
do기본 이름 및 사용자 이름을 미리 지정하려면 Credential 또는 UserName 매개 변수를 사용할 수 있습니다. UserName 매개 변수를 사용하는 경우 메시지 값도 제공해야 합니다. 아래 코드에서는 cmdlet을 사용하는 방법을 보여 줍니다. 자격 증명을 여러 번 사용할 수 있도록 자격 증명 개체를 변수에 저장할 수도 있습니다. 아래 예제에서는 자격 증명 개체가 변수 $Cred
에 저장됩니다.
$Cred = Get-Credential
$Cred = Get-Credential -Credential domain\user
$Cred = Get-Credential -UserName domain\user -Message 'Enter Password'
경우에 따라 이전 예제에 표시된 자격 증명 개체를 만드는 대화형 메서드를 사용할 수 없습니다. 대부분의 자동화 도구에는 비대화형 메서드가 필요합니다. 사용자 상호 작용 없이 자격 증명을 만들려면 암호를 포함하는 보안 문자열을 만듭니다. 그런 다음, 보안 문자열 및 사용자 이름을 메서드에 전달합니다 System.Management.Automation.PSCredential()
.
다음 명령을 사용하여 암호를 포함하는 보안 문자열을 만듭니다.
ConvertTo-SecureString "MyPlainTextPassword" -AsPlainText -Force
AsPlainText 및 Force 매개 변수가 모두 필요합니다. 이러한 매개 변수가 없으면 일반 텍스트를 보안 문자열에 전달해서는 안 된다는 메시지가 표시됩니다. 일반 텍스트 암호가 다양한 로그에 기록되기 때문에 PowerShell은 이 경고를 반환합니다. 보안 문자열을 만든 후에는 자격 증명 개체를 PSCredential()
만들려면 메서드에 전달해야 합니다. 다음 예제에서 변수 $password
는 자격 증명 개체를 포함하는 보안 문자열 $Cred
을 포함합니다.
$password = ConvertTo-SecureString "MyPlainTextPassword" -AsPlainText -Force
$Cred = New-Object System.Management.Automation.PSCredential ("username", $password)
자격 증명 개체를 만드는 방법을 알게 되었으므로 이제 PowerShell 함수에 자격 증명 매개 변수를 추가할 수 있습니다.
자격 증명 매개 변수 추가
다른 매개 변수와 마찬가지로 함수 블록에 param
추가하여 시작합니다.
기존 PowerShell cmdlet에서 사용되므로 매개 변수 이름을 $Credential
로 지정하는 것이 좋습니다. 매개 변수 형식은 [System.Management.Automation.PSCredential]
이어야 합니다.
다음 예제는 Get-Something
이라는 함수의 매개 변수 블록을 보여 줍니다. $Name
과 $Credential
이라는 두 개의 매개 변수가 있습니다.
function Get-Something {
param(
$Name,
[System.Management.Automation.PSCredential]$Credential
)
이 예제의 코드는 작업 자격 증명 매개 변수를 포함하기에 충분하지만 더 강력한 기능을 위해 추가할 수 있는 몇 가지 사항이 있습니다.
자격 증명에
[ValidateNotNull()]
전달되는 값을 검사 유효성 검사 특성을 추가합니다. 매개 변수 값이 null이면 이 특성은 잘못된 자격 증명으로 함수가 실행되지 않도록 합니다.[System.Management.Automation.Credential()]
를 추가합니다. 이렇게 하면 사용자 이름을 문자열로 전달하고 암호에 대한 대화형 프롬프트를 사용할 수 있습니다.매개 변수의 기본값을
$Credential
.로[System.Management.Automation.PSCredential]::Empty
설정합니다. 함수에서 이$Credential
개체를 기존 PowerShell cmdlet에 전달할 수 있습니다. 함수 내에서 호출된 cmdlet에 null 값을 제공하면 오류가 발생합니다. 빈 자격 증명 개체를 제공하면 이 오류가 발생하지 않습니다.
팁
자격 증명 매개 변수를 허용하는 일부 cmdlet은 예상과 달리 [System.Management.Automation.PSCredential]::Empty
를 지원하지 않습니다. 해결 방법은 레거시 Cmdlet 처리 섹션을 참조하세요.
자격 증명 매개 변수 사용
다음 예제에서는 자격 증명 매개 변수를 사용하는 방법을 보여 줍니다. 이 예제에서는 Pester Book에서 제외된 함수를 Set-RemoteRegistryValue
보여 있습니다. 이 함수는 이전 섹션에서 설명하는 기술을 사용하여 자격 증명 매개 변수를 정의합니다. 함수는 함수에서 만든 변수를 $Credential
사용하여 호출 Invoke-Command
합니다. 이렇게 하면 실행 중인 사용자를 변경할 수 있습니다 Invoke-Command
. 기본값 $Credential
은 빈 자격 증명이므로 자격 증명을 제공하지 않고 함수를 실행할 수 있습니다.
function Set-RemoteRegistryValue {
param(
$ComputerName,
$Path,
$Name,
$Value,
[ValidateNotNull()]
[System.Management.Automation.PSCredential]
[System.Management.Automation.Credential()]
$Credential = [System.Management.Automation.PSCredential]::Empty
)
$null = Invoke-Command -ComputerName $ComputerName -ScriptBlock {
Set-ItemProperty -Path $using:Path -Name $using:Name -Value $using:Value
} -Credential $Credential
}
다음 섹션에서는 Set-RemoteRegistryValue
에 자격 증명을 제공하는 다양한 방법을 보여 줍니다.
자격 증명 확인
런타임 Get-credential
에 괄호 ()
안에 사용하면 Get-Credential
먼저 실행됩니다. 사용자 이름 및 암호를 입력하라는 메시지가 표시됩니다. Get-credential
의 Credential 또는 UserName 매개 변수를 사용하여 사용자 이름과 도메인을 미리 채울 수 있습니다. 다음 예제에서는 스플래팅이라는 기술을 사용하여 함수에 매개 변수를 Set-RemoteRegistryValue
전달합니다. 스플래팅에 대한 자세한 내용은 about_Splatting 문서를 참조하세요.
$remoteKeyParams = @{
ComputerName = $env:COMPUTERNAME
Path = 'HKLM:\SOFTWARE\Microsoft\WebManagement\Server'
Name = 'EnableRemoteManagement'
Value = '1'
}
Set-RemoteRegistryValue @remoteKeyParams -Credential (Get-Credential)
(Get-Credential)
사용은 번거로워 보입니다. 일반적으로 사용자 이름만으로 Credential 매개 변수를 사용하면 cmdlet은 자동으로 암호를 묻는 메시지를 표시합니다. 이 특성은 [System.Management.Automation.Credential()]
이 동작을 사용하도록 설정합니다.
$remoteKeyParams = @{
ComputerName = $env:COMPUTERNAME
Path = 'HKLM:\SOFTWARE\Microsoft\WebManagement\Server'
Name = 'EnableRemoteManagement'
Value = '1'
}
Set-RemoteRegistryValue @remoteKeyParams -Credential duffney
참고 항목
표시된 레지스트리 값을 설정하기 위해 이러한 예제에서는 Windows의 웹 서버 기능이 설치되어 있다고 가정합니다. 필요한 경우 Install-WindowsFeature Web-Server
와 Install-WindowsFeature web-mgmt-tools
를 실행하세요.
변수에서 자격 증명 제공
미리 자격 증명 변수를 채우고 Set-RemoteRegistryValue
함수의 Credential 매개 변수에 전달할 수도 있습니다. Jenkins, TeamCity 및 Octopus Deploy와 같은 CI/CD(연속 통합/연속 배포) 도구에서 이 메서드를 사용합니다. Jenkins를 사용하는 예제의 경우 Windows에서 Jenkins 및 PowerShell을 사용하여 자동화하는 Hodge의 블로그 게시물인 2부를 검사.
이 예제는 .NET 메서드를 사용하여 암호에 전달할 보안 문자열과 자격 증명 개체를 만듭니다.
$password = ConvertTo-SecureString "P@ssw0rd" -AsPlainText -Force
$Cred = New-Object System.Management.Automation.PSCredential ("duffney", $password)
$remoteKeyParams = @{
ComputerName = $env:COMPUTERNAME
Path = 'HKLM:\SOFTWARE\Microsoft\WebManagement\Server'
Name = 'EnableRemoteManagement'
Value = '1'
}
Set-RemoteRegistryValue @remoteKeyParams -Credential $Cred
이 예제에서는 명확한 텍스트 암호를 사용하여 보안 문자열을 만듭니다. 이전에 멘션 CI/CD에는 런타임에 해당 암호를 제공하는 보안 방법이 있습니다. 이러한 도구를 사용하는 경우 사용하는 CI/CD 도구 내에서 정의된 변수로 일반 텍스트 암호를 바꾸세요.
자격 증명 없이 실행
$Credential
기본값은 빈 자격 증명 개체이므로 다음 예제와 같이 자격 증명 없이 명령을 실행할 수 있습니다.
$remoteKeyParams = @{
ComputerName = $env:COMPUTERNAME
Path = 'HKLM:\SOFTWARE\Microsoft\WebManagement\Server'
Name = 'EnableRemoteManagement'
Value = '1'
}
Set-RemoteRegistryValue @remoteKeyParams
레거시 cmdlet 처리
모든 cmdlet이 자격 증명 개체를 지원하거나 빈 자격 증명을 허용하는 것은 아닙니다. 대신 cmdlet은 사용자 이름 및 암호 매개 변수가 문자열이기를 원합니다. 이 제한 사항은 몇 가지 방법으로 해결할 수 있습니다.
if-else를 사용하여 빈 자격 증명 처리
이 시나리오에서 실행할 cmdlet은 빈 자격 증명 개체를 허용하지 않습니다. 다음은 비어 있지 않은 경우에만 자격 증명 매개 변수를 Invoke-Command
추가하는 예제입니다. 그렇지 않으면 자격 증명 매개 변수 없이 실행됩니다Invoke-Command
.
function Set-RemoteRegistryValue {
param(
$ComputerName,
$Path,
$Name,
$Value,
[ValidateNotNull()]
[System.Management.Automation.PSCredential]
[System.Management.Automation.Credential()]
$Credential = [System.Management.Automation.PSCredential]::Empty
)
if($Credential -ne [System.Management.Automation.PSCredential]::Empty) {
Invoke-Command -ComputerName:$ComputerName -Credential:$Credential {
Set-ItemProperty -Path $using:Path -Name $using:Name -Value $using:Value
}
} else {
Invoke-Command -ComputerName:$ComputerName {
Set-ItemProperty -Path $using:Path -Name $using:Name -Value $using:Value
}
}
}
스플래팅을 사용하여 빈 자격 증명 처리
이 예제는 매개 변수 스플래팅을 사용하여 레거시 cmdlet을 호출합니다. 개체는 $Credential
스플래팅을 위해 해시 테이블에 조건부로 추가되며 스크립트 블록을 반복 Invoke-Command
할 필요가 없습니다. 함수 내부 스플래팅에 대한 자세한 내용은 고급 함수 내의 스플래팅 매개 변수 블로그 게시물을 참조하세요.
function Set-RemoteRegistryValue {
param(
$ComputerName,
$Path,
$Name,
$Value,
[ValidateNotNull()]
[System.Management.Automation.PSCredential]
[System.Management.Automation.Credential()]
$Credential = [System.Management.Automation.PSCredential]::Empty
)
$Splat = @{
ComputerName = $ComputerName
}
if ($Credential -ne [System.Management.Automation.PSCredential]::Empty) {
$Splat['Credential'] = $Credential
}
$null = Invoke-Command -ScriptBlock {
Set-ItemProperty -Path $using:Path -Name $using:Name -Value $using:Value
} @splat
}
문자열 암호 작업
Invoke-Sqlcmd
cmdlet은 문자열을 암호로 허용하는 cmdlet의 예입니다.
Invoke-Sqlcmd
를 사용하면 간단한 SQL 삽입, 업데이트 및 삭제 문을 실행할 수 있습니다. Invoke-Sqlcmd
에는 보다 안전한 자격 증명 개체가 아닌 명확한 텍스트 사용자 이름 및 암호가 필요합니다. 이 예제는 자격 증명 개체에서 사용자 이름 및 암호를 추출하는 방법을 보여 줍니다.
이 예제의 함수는 Get-AllSQLDatabases
cmdlet을 Invoke-Sqlcmd
호출하여 모든 데이터베이스에 대해 SQL Server를 쿼리합니다. 이 함수는 이전 예제에서 사용된 것과 동일한 특성을 사용하여 자격 증명 매개 변수를 정의합니다. 사용자 이름 및 암호는 변수 내에 $Credential
있으므로 해당 값을 추출하여 사용할 Invoke-Sqlcmd
수 있습니다.
사용자 이름은 변수의 UserName 속성 $Credential
에서 사용할 수 있습니다. 암호를 가져오려면 개체의 $Credential
메서드를 GetNetworkCredential()
사용해야 합니다. 값은 매개 변수를 스플래팅하는 데 사용되는 해시 테이블에 추가되는 변수로 Invoke-Sqlcmd
추출됩니다.
function Get-AllSQLDatabases {
param(
$SQLServer,
[ValidateNotNull()]
[System.Management.Automation.PSCredential]
[System.Management.Automation.Credential()]
$Credential = [System.Management.Automation.PSCredential]::Empty
)
$UserName = $Credential.UserName
$Password = $Credential.GetNetworkCredential().Password
$splat = @{
UserName = $UserName
Password = $Password
ServerInstance = 'SQLServer'
Query = "Select * from Sys.Databases"
}
Invoke-Sqlcmd @splat
}
$credSplat = @{
TypeName = 'System.Management.Automation.PSCredential'
ArgumentList = 'duffney',('P@ssw0rd' | ConvertTo-SecureString -AsPlainText -Force)
}
$Credential = New-Object @credSplat
Get-AllSQLDatabases -SQLServer SQL01 -Credential $Credential
지속적인 학습 자격 증명 관리
자격 증명 개체를 안전하게 만들고 저장하는 것은 어려울 수 있습니다. 다음 리소스는 PowerShell 자격 증명을 기본 수 있습니다.
PowerShell