Dodawanie obsługi poświadczeń do funkcji programu PowerShell
Uwaga
Oryginalna wersja tego artykułu pojawiła się na blogu napisanym przez @joshduffney. Ten artykuł został edytowany w celu włączenia do tej witryny. Zespół programu PowerShell dziękuje Joshowi za udostępnienie tej zawartości. Zapoznaj się ze swoim blogiem na duffney.io.
W tym artykule pokazano, jak dodać parametry poświadczeń do funkcji programu PowerShell i dlaczego chcesz. Parametr poświadczeń umożliwia uruchamianie funkcji lub polecenia cmdlet jako inny użytkownik. Najczęstszym zastosowaniem jest uruchomienie funkcji lub polecenia cmdlet jako konta użytkownika z podwyższonym poziomem uprawnień.
Na przykład polecenie cmdlet New-ADUser
ma parametr Credential , który można podać poświadczenia administratora domeny, aby utworzyć konto w domenie. Zakładając, że normalne konto z uruchomioną sesją programu PowerShell nie ma już tego dostępu.
Tworzenie obiektu poświadczeń
Obiekt PSCredential reprezentuje zestaw poświadczeń zabezpieczeń, takich jak nazwa użytkownika i hasło. Obiekt można przekazać jako parametr do funkcji uruchamianej jako konto użytkownika w tym obiekcie poświadczeń. Istnieje kilka sposobów tworzenia obiektu poświadczeń. Pierwszym sposobem utworzenia obiektu poświadczeń jest użycie polecenia cmdlet Get-Credential
programu PowerShell . Po uruchomieniu bez parametrów zostanie wyświetlony monit o podanie nazwy użytkownika i hasła. Możesz też wywołać polecenie cmdlet z kilkoma parametrami opcjonalnymi.
Aby określić nazwę domeny i nazwę użytkownika przed upływem czasu, możesz użyć parametrów Credential lub UserName . Jeśli używasz parametru UserName, musisz również podać wartość komunikatu. Poniższy kod demonstruje użycie polecenia cmdlet . Możesz również przechowywać obiekt poświadczeń w zmiennej, aby można było wielokrotnie używać poświadczeń. W poniższym przykładzie obiekt poświadczeń jest przechowywany w zmiennej $Cred
.
$Cred = Get-Credential
$Cred = Get-Credential -Credential domain\user
$Cred = Get-Credential -UserName domain\user -Message 'Enter Password'
Czasami nie można użyć metody interaktywnej tworzenia obiektów poświadczeń pokazanych w poprzednim przykładzie. Większość narzędzi automatyzacji wymaga metody nieinterakcyjnej. Aby utworzyć poświadczenia bez interakcji użytkownika, utwórz bezpieczny ciąg zawierający hasło. Następnie przekaż bezpieczny ciąg i nazwę użytkownika do System.Management.Automation.PSCredential()
metody .
Użyj następującego polecenia, aby utworzyć bezpieczny ciąg zawierający hasło:
ConvertTo-SecureString "MyPlainTextPassword" -AsPlainText -Force
Wymagane są zarówno parametry AsPlainText, jak i Force. Bez tych parametrów zostanie wyświetlone ostrzeżenie o tym, że nie należy przekazywać zwykłego tekstu do bezpiecznego ciągu. Program PowerShell zwraca to ostrzeżenie, ponieważ hasło w postaci zwykłego tekstu jest rejestrowane w różnych dziennikach. Po utworzeniu bezpiecznego ciągu należy przekazać go do PSCredential()
metody , aby utworzyć obiekt poświadczeń. W poniższym przykładzie zmienna $password
zawiera bezpieczny ciąg $Cred
zawierający obiekt poświadczeń.
$password = ConvertTo-SecureString "MyPlainTextPassword" -AsPlainText -Force
$Cred = New-Object System.Management.Automation.PSCredential ("username", $password)
Teraz, gdy już wiesz, jak tworzyć obiekty poświadczeń, możesz dodać parametry poświadczeń do funkcji programu PowerShell.
Dodawanie parametru poświadczeń
Podobnie jak każdy inny parametr, zacznij od dodania go do param
bloku funkcji.
Zaleca się nadanie parametrowi nazwy parametru $Credential
, ponieważ są używane istniejące polecenia cmdlet programu PowerShell. Typ parametru powinien mieć wartość [System.Management.Automation.PSCredential]
.
W poniższym przykładzie przedstawiono blok parametrów dla funkcji o nazwie Get-Something
. Ma dwa parametry: $Name
i $Credential
.
function Get-Something {
param(
$Name,
[System.Management.Automation.PSCredential]$Credential
)
Kod w tym przykładzie wystarczy, aby mieć działający parametr poświadczeń, jednak istnieje kilka rzeczy, które można dodać, aby uczynić go bardziej niezawodnym.
Dodaj atrybut weryfikacji,
[ValidateNotNull()]
aby sprawdzić, czy wartość przekazywana do poświadczenia. Jeśli wartość parametru ma wartość null, ten atrybut uniemożliwia wykonywanie funkcji z nieprawidłowymi poświadczeniami.Dodaj
[System.Management.Automation.Credential()]
element . Umożliwia to przekazanie nazwy użytkownika jako ciągu i wyświetlenie interakcyjnego monitu o hasło.Ustaw wartość domyślną parametru
$Credential
na[System.Management.Automation.PSCredential]::Empty
wartość . Twoja funkcja może przekazywać ten$Credential
obiekt do istniejących poleceń cmdlet programu PowerShell. Podanie wartości null do polecenia cmdlet o nazwie wewnątrz funkcji powoduje błąd. Podanie pustego obiektu poświadczeń pozwala uniknąć tego błędu.
Napiwek
Niektóre polecenia cmdlet, które akceptują parametr poświadczeń, nie obsługują [System.Management.Automation.PSCredential]::Empty
tak, jak powinny. Aby obejść ten problem, zobacz sekcję Obsługa starszych poleceń cmdlet .
Używanie parametrów poświadczeń
W poniższym przykładzie pokazano, jak używać parametrów poświadczeń. W tym przykładzie pokazano funkcję o nazwie Set-RemoteRegistryValue
, która znajduje się poza książką Pester. Ta funkcja definiuje parametr poświadczeń przy użyciu technik opisanych w poprzedniej sekcji. Funkcja wywołuje Invoke-Command
zmienną utworzoną $Credential
przez funkcję. Umożliwia to zmianę użytkownika, który jest uruchomiony Invoke-Command
. Ponieważ wartość $Credential
domyślna to puste poświadczenie, funkcja może działać bez podawania poświadczeń.
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
}
W poniższych sekcjach przedstawiono różne metody podawania poświadczeń do Set-RemoteRegistryValue
usługi .
Monitowanie o poświadczenia
Użycie Get-Credential
w nawiasach ()
w czasie wykonywania powoduje Get-credential
, że polecenie jest uruchamiane jako pierwsze. Zostanie wyświetlony monit o podanie nazwy użytkownika i hasła. Możesz użyć parametrów Credential lub UserName polecenia Get-credential
, aby wstępnie wypełnić nazwę użytkownika i domenę. W poniższym przykładzie użyto techniki o nazwie splatting w celu przekazania parametrów do Set-RemoteRegistryValue
funkcji. Aby uzyskać więcej informacji na temat splattingu, zapoznaj się z artykułem about_Splatting .
$remoteKeyParams = @{
ComputerName = $env:COMPUTERNAME
Path = 'HKLM:\SOFTWARE\Microsoft\WebManagement\Server'
Name = 'EnableRemoteManagement'
Value = '1'
}
Set-RemoteRegistryValue @remoteKeyParams -Credential (Get-Credential)
Używanie (Get-Credential)
wydaje się kłopotliwe. Zwykle, gdy używasz parametru Credential tylko z nazwą użytkownika, polecenie cmdlet automatycznie wyświetla monit o hasło. Atrybut [System.Management.Automation.Credential()]
umożliwia to zachowanie.
$remoteKeyParams = @{
ComputerName = $env:COMPUTERNAME
Path = 'HKLM:\SOFTWARE\Microsoft\WebManagement\Server'
Name = 'EnableRemoteManagement'
Value = '1'
}
Set-RemoteRegistryValue @remoteKeyParams -Credential duffney
Uwaga
Aby ustawić pokazaną wartość rejestru, w tych przykładach założono, że masz zainstalowane funkcje serwera sieci Web systemu Windows. Uruchom polecenie Install-WindowsFeature Web-Server
i Install-WindowsFeature web-mgmt-tools
, jeśli jest to wymagane.
Podawanie poświadczeń w zmiennej
Możesz również wypełnić zmienną poświadczeń z wyprzedzeniem i przekazać ją do parametru Set-RemoteRegistryValue
Credential funkcji. Użyj tej metody z narzędziami ciągłej integracji/ciągłego wdrażania (CI/CD), takimi jak Jenkins, TeamCity i Octopus Deploy. Aby zapoznać się z przykładem użycia narzędzia Jenkins, zapoznaj się z wpisem w blogu Hodge Automating with Jenkins and PowerShell on Windows - Part 2 (Automatyzacja za pomocą narzędzia Jenkins i programu PowerShell w systemie Windows — część 2).
W tym przykładzie użyto metody .NET, aby utworzyć obiekt poświadczeń i bezpieczny ciąg do przekazania hasła.
$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
W tym przykładzie bezpieczny ciąg jest tworzony przy użyciu hasła zwykłego tekstu. Wszystkie wymienione wcześniej ciągła integracja/ciągłe wdrażanie mają bezpieczną metodę zapewniania tego hasła w czasie wykonywania. W przypadku korzystania z tych narzędzi zastąp hasło zwykłego tekstu zmienną zdefiniowaną w używanym narzędziu ciągłej integracji/ciągłego wdrażania.
Uruchamianie bez poświadczeń
Ponieważ $Credential
domyślnie jest to pusty obiekt poświadczeń, można uruchomić polecenie bez poświadczeń, jak pokazano w tym przykładzie:
$remoteKeyParams = @{
ComputerName = $env:COMPUTERNAME
Path = 'HKLM:\SOFTWARE\Microsoft\WebManagement\Server'
Name = 'EnableRemoteManagement'
Value = '1'
}
Set-RemoteRegistryValue @remoteKeyParams
Obsługa starszych poleceń cmdlet
Nie wszystkie polecenia cmdlet obsługują obiekty poświadczeń lub zezwalają na puste poświadczenia. Zamiast tego polecenie cmdlet chce użyć parametrów nazwy użytkownika i hasła jako ciągów. Istnieje kilka sposobów obejścia tego ograniczenia.
Używanie instrukcji if-else do obsługi pustych poświadczeń
W tym scenariuszu polecenie cmdlet, które chcesz uruchomić, nie akceptuje pustego obiektu poświadczeń. W tym przykładzie dodano parametr Credential tylko Invoke-Command
wtedy, gdy nie jest pusty. W przeciwnym razie uruchamia Invoke-Command
parametr bez poświadczeń .
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
}
}
}
Używanie splattingu do obsługi pustych poświadczeń
W tym przykładzie użyto splattingu parametrów w celu wywołania starszego polecenia cmdlet. $Credential
Obiekt jest warunkowo dodawany do tabeli skrótów w celu splatania i unika konieczności powtarzania bloku skryptuInvoke-Command
. Aby dowiedzieć się więcej na temat splattingu wewnątrz funkcji, zobacz wpis w blogu Splatting Parameters Inside Advanced Functions (Parametryplatting Inside Advanced Functions ).
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
}
Praca z hasłami ciągów
Polecenie Invoke-Sqlcmd
cmdlet jest przykładem polecenia cmdlet, które akceptuje ciąg jako hasło.
Invoke-Sqlcmd
umożliwia uruchamianie prostych instrukcji wstawiania, aktualizowania i usuwania sql. Invoke-Sqlcmd
wymaga nazwy użytkownika i hasła w postaci zwykłego tekstu, a nie bezpieczniejszego obiektu poświadczeń. W tym przykładzie pokazano, jak wyodrębnić nazwę użytkownika i hasło z obiektu poświadczeń.
Funkcja Get-AllSQLDatabases
w tym przykładzie Invoke-Sqlcmd
wywołuje polecenie cmdlet, aby wysłać zapytanie do serwera SQL dla wszystkich jego baz danych. Funkcja definiuje parametr Credential z tym samym atrybutem używanym w poprzednich przykładach. Ponieważ nazwa użytkownika i hasło istnieją w zmiennej $Credential
, możesz wyodrębnić te wartości do użycia z Invoke-Sqlcmd
.
Nazwa użytkownika jest dostępna we właściwości UserName zmiennej $Credential
. Aby uzyskać hasło, należy użyć GetNetworkCredential()
metody $Credential
obiektu . Wartości są wyodrębniane do zmiennych, które są dodawane do tabeli skrótów używanej do splatting parametrów do 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
Ciągłe uczenie się zarządzania poświadczeniami
Bezpieczne tworzenie i przechowywanie obiektów poświadczeń może być trudne. Poniższe zasoby mogą pomóc w utrzymywaniu poświadczeń programu PowerShell.