Referentieondersteuning toevoegen aan PowerShell-functies
Notitie
De oorspronkelijke versie van dit artikel verscheen op het blog dat is geschreven door @joshduffney. Dit artikel is bewerkt voor opname op deze site. Het PowerShell-team bedankt Josh voor het delen van deze inhoud met ons. Bekijk zijn blog op duffney.io.
In dit artikel leest u hoe u referentieparameters toevoegt aan PowerShell-functies en waarom u dat wilt. Met een referentieparameter kunt u de functie of cmdlet als een andere gebruiker uitvoeren. Het meest voorkomende gebruik is het uitvoeren van de functie of cmdlet als een gebruikersaccount met verhoogde bevoegdheid.
De cmdlet New-ADUser
heeft bijvoorbeeld een referentieparameter , waarmee u domeinbeheerdersreferenties kunt opgeven om een account in een domein te maken. Ervan uitgaande dat uw normale account waarop de PowerShell-sessie wordt uitgevoerd, nog geen toegang heeft.
Referentieobject maken
Het PSCredential-object vertegenwoordigt een set beveiligingsreferenties, zoals een gebruikersnaam en wachtwoord. Het object kan worden doorgegeven als een parameter aan een functie die wordt uitgevoerd als het gebruikersaccount in dat referentieobject. Er zijn een aantal manieren waarop u een referentieobject kunt maken. De eerste manier om een referentieobject te maken, is door de PowerShell-cmdlet Get-Credential
te gebruiken. Wanneer u zonder parameters uitvoert, wordt u gevraagd om een gebruikersnaam en wachtwoord. U kunt de cmdlet ook aanroepen met enkele optionele parameters.
Als u de domeinnaam en gebruikersnaam van tevoren wilt opgeven, kunt u de parameters Referentie of Gebruikersnaam gebruiken. Wanneer u de parameter UserName gebruikt, moet u ook een berichtwaarde opgeven. De onderstaande code laat zien hoe u de cmdlet gebruikt. U kunt het referentieobject ook opslaan in een variabele, zodat u de referentie meerdere keren kunt gebruiken. In het onderstaande voorbeeld wordt het referentieobject opgeslagen in de variabele $Cred
.
$Cred = Get-Credential
$Cred = Get-Credential -Credential domain\user
$Cred = Get-Credential -UserName domain\user -Message 'Enter Password'
Soms kunt u de interactieve methode voor het maken van referentieobjecten die in het vorige voorbeeld worden weergegeven, niet gebruiken. Voor de meeste automatiseringshulpprogramma's is een niet-interactieve methode vereist. Als u een referentie wilt maken zonder tussenkomst van de gebruiker, maakt u een beveiligde tekenreeks met het wachtwoord. Geef vervolgens de beveiligde tekenreeks en gebruikersnaam door aan de System.Management.Automation.PSCredential()
methode.
Gebruik de volgende opdracht om een beveiligde tekenreeks te maken die het wachtwoord bevat:
ConvertTo-SecureString "MyPlainTextPassword" -AsPlainText -Force
De parameters AsPlainText en Force zijn vereist. Zonder deze parameters ontvangt u een berichtwaarschuwing dat u geen tekst zonder opmaak moet doorgeven aan een beveiligde tekenreeks. PowerShell retourneert deze waarschuwing omdat het wachtwoord voor tekst zonder opmaak wordt vastgelegd in verschillende logboeken. Nadat u een beveiligde tekenreeks hebt gemaakt, moet u deze doorgeven aan de PSCredential()
methode om het referentieobject te maken. In het volgende voorbeeld bevat de variabele $password
de beveiligde tekenreeks $Cred
het referentieobject.
$password = ConvertTo-SecureString "MyPlainTextPassword" -AsPlainText -Force
$Cred = New-Object System.Management.Automation.PSCredential ("username", $password)
Nu u weet hoe u referentieobjecten maakt, kunt u referentieparameters toevoegen aan uw PowerShell-functies.
Een referentieparameter toevoegen
Net als elke andere parameter begint u door deze toe te voegen aan het param
blok van uw functie.
Het is raadzaam om de parameter $Credential
een naam te gegeven, omdat dat is wat bestaande PowerShell-cmdlets gebruiken. Het type van de parameter moet zijn [System.Management.Automation.PSCredential]
.
In het volgende voorbeeld ziet u het parameterblok voor een functie die wordt aangeroepen Get-Something
. Het heeft twee parameters: $Name
en $Credential
.
function Get-Something {
param(
$Name,
[System.Management.Automation.PSCredential]$Credential
)
De code in dit voorbeeld is voldoende om een werkende referentieparameter te hebben, maar er zijn een paar dingen die u kunt toevoegen om deze robuuster te maken.
Voeg het
[ValidateNotNull()]
validatiekenmerk toe om te controleren of de waarde die wordt doorgegeven aan referentie. Als de parameterwaarde null is, voorkomt dit kenmerk dat de functie wordt uitgevoerd met ongeldige referenties.Toevoegen
[System.Management.Automation.Credential()]
. Hiermee kunt u een gebruikersnaam doorgeven als een tekenreeks en een interactieve prompt voor het wachtwoord hebben.Stel een standaardwaarde voor de
$Credential
parameter in op[System.Management.Automation.PSCredential]::Empty
. Uw functie geeft dit$Credential
object mogelijk door aan bestaande PowerShell-cmdlets. Als u een null-waarde opgeeft voor de cmdlet die in uw functie wordt aangeroepen, wordt een fout veroorzaakt. Het opgeven van een leeg referentieobject voorkomt deze fout.
Tip
Sommige cmdlets die een referentieparameter accepteren, worden niet naar behoren ondersteund [System.Management.Automation.PSCredential]::Empty
. Zie de sectie Omgaan met verouderde cmdlets voor een tijdelijke oplossing.
Referentieparameters gebruiken
In het volgende voorbeeld ziet u hoe u referentieparameters gebruikt. In dit voorbeeld ziet u een functie die uit the Pester Book is aangeroepenSet-RemoteRegistryValue
. Deze functie definieert de referentieparameter met behulp van de technieken die in de vorige sectie worden beschreven. De functie roept Invoke-Command
aan met behulp van de $Credential
variabele die door de functie is gemaakt. Hiermee kunt u de gebruiker wijzigen die wordt uitgevoerd Invoke-Command
. Omdat de standaardwaarde $Credential
een lege referentie is, kan de functie worden uitgevoerd zonder referenties op te geven.
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
}
In de volgende secties ziet u verschillende methoden voor het opgeven van referenties.Set-RemoteRegistryValue
Vragen om referenties
Als Get-Credential
u haakjes ()
gebruikt tijdens runtime, wordt de Get-credential
uitvoering eerst uitgevoerd. U wordt gevraagd om een gebruikersnaam en wachtwoord. U kunt de parameters Get-credential
Referentie of Gebruikersnaam gebruiken om de gebruikersnaam en het domein vooraf in te vullen. In het volgende voorbeeld wordt een techniek met de naam splatting gebruikt om parameters door te geven aan de Set-RemoteRegistryValue
functie. Raadpleeg het about_Splatting artikel voor meer informatie over splatting.
$remoteKeyParams = @{
ComputerName = $env:COMPUTERNAME
Path = 'HKLM:\SOFTWARE\Microsoft\WebManagement\Server'
Name = 'EnableRemoteManagement'
Value = '1'
}
Set-RemoteRegistryValue @remoteKeyParams -Credential (Get-Credential)
Het gebruik (Get-Credential)
lijkt omslachtig. Normaal gesproken vraagt de cmdlet automatisch om het wachtwoord wanneer u de parameter Referentie gebruikt met alleen een gebruikersnaam. Met [System.Management.Automation.Credential()]
het kenmerk wordt dit gedrag ingeschakeld.
$remoteKeyParams = @{
ComputerName = $env:COMPUTERNAME
Path = 'HKLM:\SOFTWARE\Microsoft\WebManagement\Server'
Name = 'EnableRemoteManagement'
Value = '1'
}
Set-RemoteRegistryValue @remoteKeyParams -Credential duffney
Notitie
Als u de weergegeven registerwaarde wilt instellen, wordt in deze voorbeelden ervan uitgegaan dat de webserverfuncties van Windows zijn geïnstalleerd. Uitvoeren Install-WindowsFeature Web-Server
en Install-WindowsFeature web-mgmt-tools
indien nodig.
Referenties opgeven in een variabele
U kunt een referentievariabele ook van tevoren invullen en doorgeven aan de parameter Referentie van Set-RemoteRegistryValue
de functie. Gebruik deze methode met CI/CD-hulpprogramma's (Continuous Integration/ Continuous Deployment), zoals Jenkins, TeamCity en Octopus Deploy. Bekijk voor een voorbeeld van Jenkins het blogbericht van Hodge automatiseren met Jenkins en PowerShell in Windows - deel 2.
In dit voorbeeld wordt de .NET-methode gebruikt om het referentieobject en een beveiligde tekenreeks te maken om het wachtwoord door te geven.
$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
In dit voorbeeld wordt de beveiligde tekenreeks gemaakt met een wachtwoord voor duidelijke tekst. Alle eerder genoemde CI/CD hebben een veilige methode om dat wachtwoord op te geven tijdens runtime. Wanneer u deze hulpprogramma's gebruikt, vervangt u het wachtwoord voor tekst zonder opmaak door de variabele die is gedefinieerd in het CI/CD-hulpprogramma dat u gebruikt.
Uitvoeren zonder referenties
Aangezien $Credential
standaard een leeg referentieobject is, kunt u de opdracht zonder referenties uitvoeren, zoals wordt weergegeven in dit voorbeeld:
$remoteKeyParams = @{
ComputerName = $env:COMPUTERNAME
Path = 'HKLM:\SOFTWARE\Microsoft\WebManagement\Server'
Name = 'EnableRemoteManagement'
Value = '1'
}
Set-RemoteRegistryValue @remoteKeyParams
Omgaan met verouderde cmdlets
Niet alle cmdlets ondersteunen referentieobjecten of staan lege referenties toe. In plaats daarvan wil de cmdlet gebruikersnaam- en wachtwoordparameters als tekenreeksen. Er zijn een aantal manieren om deze beperking te omzeilen.
If-else gebruiken om lege referenties af te handelen
In dit scenario accepteert de cmdlet die u wilt uitvoeren geen leeg referentieobject. In dit voorbeeld wordt de referentieparameter alleen toegevoegd als Invoke-Command
deze niet leeg is. Anders wordt de Invoke-Command
parameter Referentie uitgevoerd zonder de referentieparameter .
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
}
}
}
Splatting gebruiken om lege referenties te verwerken
In dit voorbeeld wordt parameter-splatting gebruikt om de verouderde cmdlet aan te roepen. Het $Credential
object wordt voorwaardelijk toegevoegd aan de hash-tabel voor splatting en voorkomt dat het Invoke-Command
scriptblok moet worden herhaald. Zie het blogbericht Splatting Parameters Inside Advanced Functions voor meer informatie over het splatten van functies.
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
}
Werken met tekenreekswachtwoorden
De Invoke-Sqlcmd
cmdlet is een voorbeeld van een cmdlet die een tekenreeks accepteert als een wachtwoord.
Invoke-Sqlcmd
hiermee kunt u eenvoudige INSTRUCTIES voor invoegen, bijwerken en verwijderen van SQL uitvoeren. Invoke-Sqlcmd
vereist een duidelijke tekst gebruikersnaam en wachtwoord in plaats van een veiliger referentieobject. In dit voorbeeld ziet u hoe u de gebruikersnaam en het wachtwoord kunt extraheren uit een referentieobject.
Met Get-AllSQLDatabases
de functie in dit voorbeeld wordt de cmdlet aangeroepen Invoke-Sqlcmd
om een query uit te voeren op een SQL-server voor alle bijbehorende databases. De functie definieert een referentieparameter met hetzelfde kenmerk dat in de vorige voorbeelden wordt gebruikt. Aangezien de gebruikersnaam en het wachtwoord in de $Credential
variabele bestaan, kunt u deze waarden extraheren voor gebruik met Invoke-Sqlcmd
.
De gebruikersnaam is beschikbaar via de eigenschap UserName van de $Credential
variabele. Als u het wachtwoord wilt ophalen, moet u de GetNetworkCredential()
methode van het $Credential
object gebruiken. De waarden worden geëxtraheerd in variabelen die worden toegevoegd aan een hash-tabel die wordt gebruikt voor het splatten van parameters.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
Voortgezet leerreferentiebeheer
Het veilig maken en opslaan van referentieobjecten kan lastig zijn. Met de volgende bronnen kunt u PowerShell-referenties onderhouden.