Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Annotazioni
La versione originale di questo articolo è apparsa sul blog scritto da @joshduffney. Questo articolo è stato modificato per l'inclusione in questo sito. Il team di PowerShell ringrazia Josh per condividere questo contenuto con noi. Per favore, consulta il suo blog all'indirizzo duffney.io.
Questo articolo illustra come aggiungere parametri delle credenziali alle funzioni di PowerShell e perché si vuole. Un parametro delle credenziali consente di eseguire la funzione o il cmdlet come utente diverso. L'uso più comune consiste nell'eseguire la funzione o il cmdlet come account utente con privilegi elevati.
Ad esempio, il cmdlet New-ADUser
ha un parametro Credential , che è possibile fornire credenziali di amministratore di dominio per creare un account in un dominio. Supponendo che l'account normale che esegue la sessione di PowerShell non abbia già tale accesso.
Creazione di un oggetto credenziale
L'oggetto PSCredential rappresenta un set di credenziali di sicurezza, ad esempio un nome utente e una password. L'oggetto può essere passato come parametro a una funzione eseguita come account utente in tale oggetto credenziale. Esistono alcuni modi per creare un oggetto credenziale. Il primo modo per creare un oggetto credenziale consiste nell'usare il cmdlet Get-Credential
di PowerShell . Quando si esegue senza parametri, viene richiesto un nome utente e una password. In alternativa, è possibile chiamare il cmdlet con alcuni parametri facoltativi.
Per specificare il nome di dominio e il nome utente in anticipo, è possibile usare i parametri Credential o UserName . Quando si usa il parametro UserName , è necessario specificare anche un valore Message . Il codice seguente illustra l'uso del cmdlet . È anche possibile archiviare l'oggetto credenziale in una variabile in modo che sia possibile usare le credenziali più volte. Nell'esempio seguente l'oggetto credenziale viene archiviato nella variabile $Cred
.
$Cred = Get-Credential
$Cred = Get-Credential -Credential domain\user
$Cred = Get-Credential -UserName domain\user -Message 'Enter Password'
In alcuni casi, non è possibile usare il metodo interattivo per la creazione di oggetti credenziali illustrati nell'esempio precedente. La maggior parte degli strumenti di automazione richiede un metodo non interattivo. Per creare credenziali senza interazione dell'utente, creare una stringa sicura contenente la password. Passare quindi la stringa sicura e il nome utente al System.Management.Automation.PSCredential()
metodo .
Usare il comando seguente per creare una stringa sicura contenente la password:
ConvertTo-SecureString "MyPlainTextPassword" -AsPlainText -Force
Sono necessari entrambi i parametri AsPlainText e Force . Senza questi parametri, viene visualizzato un messaggio di avviso che indica che non è consigliabile passare testo normale in una stringa sicura. PowerShell restituisce questo avviso perché la password di testo normale viene registrata in vari log. Dopo aver creato una stringa sicura, è necessario passarla al PSCredential()
metodo per creare l'oggetto credenziale. Nell'esempio seguente la variabile $password
contiene la stringa $Cred
protetta contenente l'oggetto credenziale.
$password = ConvertTo-SecureString "MyPlainTextPassword" -AsPlainText -Force
$Cred = New-Object System.Management.Automation.PSCredential ("username", $password)
Ora che si è appreso come creare oggetti credenziali, è possibile aggiungere parametri delle credenziali alle funzioni di PowerShell.
Aggiungere un parametro delle credenziali
Proprio come qualsiasi altro parametro, si inizia aggiungendolo nel param
blocco della funzione.
È consigliabile assegnare al parametro $Credential
il nome utilizzato dai cmdlet di PowerShell esistenti. Il tipo del parametro deve essere [System.Management.Automation.PSCredential]
.
Nell'esempio seguente viene illustrato il blocco di parametri per una funzione denominata Get-Something
. Ha due parametri: $Name
e $Credential
.
function Get-Something {
param(
$Name,
[System.Management.Automation.PSCredential]$Credential
)
Il codice in questo esempio è sufficiente per avere un parametro di credenziale funzionante, ma esistono alcuni elementi che è possibile aggiungere per renderlo più affidabile.
Aggiungere l'attributo
[ValidateNotNull()]
di convalida per verificare che il valore passato a Credential. Se il valore del parametro è Null, questo attributo impedisce l'esecuzione della funzione con credenziali non valide.Aggiungere
[System.Management.Automation.Credential()]
. In questo modo è possibile passare un nome utente come stringa e richiedere la password in modo interattivo.Impostare un valore predefinito per il
$Credential
parametro su[System.Management.Automation.PSCredential]::Empty
. È possibile che la funzione passi questo$Credential
oggetto ai cmdlet di PowerShell esistenti. Se si specifica un valore Null al cmdlet chiamato all'interno della funzione, viene generato un errore. Se si specifica un oggetto credenziale vuoto, si evita questo errore.
Suggerimento
Alcuni cmdlet che accettano un parametro delle credenziali non supportano [System.Management.Automation.PSCredential]::Empty
come dovrebbero. Per una soluzione alternativa, vedere la sezione Gestione dei cmdlet legacy .
Uso dei parametri delle credenziali
Nell'esempio seguente viene illustrato come usare i parametri delle credenziali. In questo esempio viene illustrata una funzione denominata Set-RemoteRegistryValue
, che è fuori da The Pester Book. Questa funzione definisce il parametro delle credenziali usando le tecniche descritte nella sezione precedente. La funzione chiama Invoke-Command
usando la $Credential
variabile creata dalla funzione . In questo modo è possibile modificare l'utente che esegue Invoke-Command
. Poiché il valore predefinito di $Credential
è una credenziale vuota, la funzione può essere eseguita senza fornire credenziali.
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
}
Le sezioni seguenti illustrano diversi metodi per fornire le credenziali a Set-RemoteRegistryValue
.
Richiesta di credenziali
Se si usano Get-Credential
tra parentesi ()
in fase di esecuzione, l'oggetto Get-Credential
viene eseguito per primo. Viene richiesto un nome utente e una password. È possibile usare i parametri Credential o UserName di Get-Credential
per precompilare il nome utente e il dominio. Nell'esempio seguente viene utilizzata una tecnica chiamata splatting per passare i parametri alla funzione Set-RemoteRegistryValue
. Per ulteriori informazioni sulla splatting, consulta l'articolo about_Splatting.
$remoteKeyParams = @{
ComputerName = $Env:COMPUTERNAME
Path = 'HKLM:\SOFTWARE\Microsoft\WebManagement\Server'
Name = 'EnableRemoteManagement'
Value = '1'
}
Set-RemoteRegistryValue @remoteKeyParams -Credential (Get-Credential)
L'uso (Get-Credential)
sembra complesso. In genere, quando si usa il parametro Credential con solo un nome utente, il cmdlet richiede automaticamente la password. L'attributo [System.Management.Automation.Credential()]
abilita questo comportamento.
$remoteKeyParams = @{
ComputerName = $Env:COMPUTERNAME
Path = 'HKLM:\SOFTWARE\Microsoft\WebManagement\Server'
Name = 'EnableRemoteManagement'
Value = '1'
}
Set-RemoteRegistryValue @remoteKeyParams -Credential duffney
Annotazioni
Per impostare il valore del Registro di sistema visualizzato, questi esempi presuppongono che siano installate le funzionalità server Web di Windows. Eseguire Install-WindowsFeature Web-Server
e Install-WindowsFeature web-mgmt-tools
se necessario.
Specificare le credenziali in una variabile
È anche possibile popolare una variabile delle credenziali in anticipo e passarla al parametro Credential della Set-RemoteRegistryValue
funzione. Usare questo metodo con strumenti di integrazione continua/distribuzione continua (CI/CD), ad esempio Jenkins, TeamCity e Octopus Deploy. Per un esempio relativo all'uso di Jenkins, vedere il post di blog di Hodge Automating with Jenkins and PowerShell on Windows - Part 2 (Automazione con Jenkins e PowerShell in Windows - Parte 2).
In questo esempio viene usato il metodo .NET per creare l'oggetto credenziali e una stringa sicura come input per la password.
$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
Per questo esempio, la stringa protetta viene creata usando una password di testo non crittografato. Tutti i CI/CD indicati in precedenza hanno un metodo sicuro per fornire tale password in fase di esecuzione. Quando si usano questi strumenti, sostituire la password di testo normale con la variabile definita nello strumento CI/CD usato.
Esegui senza credenziali
Poiché $Credential
l'impostazione predefinita è un oggetto credenziali vuoto, è possibile eseguire il comando senza credenziali, come illustrato in questo esempio:
$remoteKeyParams = @{
ComputerName = $Env:COMPUTERNAME
Path = 'HKLM:\SOFTWARE\Microsoft\WebManagement\Server'
Name = 'EnableRemoteManagement'
Value = '1'
}
Set-RemoteRegistryValue @remoteKeyParams
Gestione dei cmdlet legacy
Non tutti i cmdlet supportano oggetti credenziali o consentono credenziali vuote. Il cmdlet desidera invece parametri nome utente e password come stringhe. Esistono alcuni modi per aggirare questa limitazione.
Uso di if-else per gestire credenziali vuote
In questo scenario, il cmdlet da eseguire non accetta un oggetto credenziale vuoto. In questo esempio, il parametro Credential viene aggiunto a Invoke-Command
solo se non è vuoto. In caso contrario, esegue Invoke-Command
senza il parametro Credential .
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
}
}
}
Uso dello splatting per gestire le credenziali vuote
In questo esempio viene usato lo splatting dei parametri per chiamare il cmdlet legacy. L'oggetto $Credential
viene aggiunto alla tabella hash in modo condizionale per lo splatting, evitando la necessità di ripetere il blocco di script Invoke-Command
. Per ulteriori informazioni sullo splatting all'interno delle funzioni, vedere il post di blog Splatting Parameters Inside Advanced Functions (Parametri di splatting all'interno di funzioni avanzate).
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
}
Uso delle password delle stringhe
Il Invoke-Sqlcmd
cmdlet è un esempio di cmdlet che accetta una stringa come password.
Invoke-Sqlcmd
consente di eseguire semplici istruzioni di inserimento, aggiornamento ed eliminazione di SQL.
Invoke-Sqlcmd
richiede un nome utente e una password non crittografati anziché un oggetto credenziali più sicuro. Questo esempio illustra come estrarre il nome utente e la password da un oggetto credenziale.
La Get-AllSQLDatabases
funzione in questo esempio chiama il Invoke-Sqlcmd
cmdlet per eseguire query su un server SQL per tutti i relativi database. La funzione definisce un parametro Credential con lo stesso attributo usato negli esempi precedenti. Poiché il nome utente e la password esistono all'interno della $Credential
variabile, è possibile estrarre tali valori da usare con Invoke-Sqlcmd
.
Il nome utente è disponibile dalla proprietà UserName della $Credential
variabile. Per ottenere la password, è necessario usare il GetNetworkCredential()
metodo dell'oggetto $Credential
. I valori vengono estratti in variabili aggiunte a una tabella hash usata per il "splatting" dei parametri in 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
Gestione continua delle credenziali di apprendimento
La creazione e l'archiviazione di oggetti credenziali in modo sicuro possono risultare difficili. Le risorse seguenti consentono di gestire le credenziali di PowerShell.