PowerShell
Remot PowerShell
Ricerca…
Osservazioni
Abilitazione di Remot PowerShell
Il servizio remoto di PowerShell deve essere prima abilitato sul server a cui si desidera connettersi in remoto.
Enable-PSRemoting -Force
Questo comando esegue quanto segue:
- Esegue il cmdlet Set-WSManQuickConfig, che esegue le seguenti attività:
- Avvia il servizio WinRM.
- Imposta il tipo di avvio sul servizio WinRM su Automatico.
- Crea un listener per accettare richieste su qualsiasi indirizzo IP, se non ne esiste già uno.
- Abilita un'eccezione firewall per le comunicazioni WS-Management.
- Registra le configurazioni di sessione Microsoft.PowerShell e Microsoft.PowerShell.Workflow, se non sono già state registrate.
- Registra la configurazione della sessione Microsoft.PowerShell32 su computer a 64 bit, se non è già registrata.
- Abilita tutte le configurazioni di sessione.
- Cambia il descrittore di sicurezza di tutte le configurazioni di sessione per consentire l'accesso remoto.
- Riavvia il servizio WinRM per rendere effettive le modifiche precedenti.
Solo per ambienti non di dominio
Per i server in un dominio AD l'autenticazione remota PS avviene tramite Kerberos ('Default'), o NTLM ('Negoziare'). Se si desidera consentire la comunicazione remota a un server non di dominio, sono disponibili due opzioni.
Configurare la comunicazione WSMan su HTTPS (che richiede la generazione di certificati) o abilitare l'autenticazione di base che invia le credenziali attraverso la codifica base64-codificata (che è fondamentalmente la stessa di testo in chiaro, quindi fai attenzione a questo).
In entrambi i casi dovrai aggiungere i sistemi remoti all'elenco di host attendibili di WSMan.
Abilitazione dell'autenticazione di base
Set-Item WSMan:\localhost\Service\AllowUnencrypted $true
Poi sul computer che si desidera connettersi da, si deve dire che a fidarsi di computer che si sta collegando.
Set-Item WSMan:\localhost\Client\TrustedHosts '192.168.1.1,192.168.1.2'
Set-Item WSMan:\localhost\Client\TrustedHosts *.contoso.com
Set-Item WSMan:\localhost\Client\TrustedHosts *
Importante : devi dire al tuo cliente di considerare affidabile il computer indirizzato nel modo in cui vuoi connetterti (ad esempio se ti connetti tramite IP, deve avere fiducia nell'IP e non nel nome host)
Connessione a un server remoto tramite PowerShell
Utilizzo delle credenziali dal tuo computer locale:
Enter-PSSession 192.168.1.1
Richiesta di credenziali sul computer remoto
Enter-PSSession 192.168.1.1 -Credential $(Get-Credential)
Esegui comandi su un computer remoto
Una volta abilitato il servizio remoto di Powershell (Enable-PSRemoting) È possibile eseguire comandi sul computer remoto come questo:
Invoke-Command -ComputerName "RemoteComputerName" -ScriptBlock {
Write host "Remote Computer Name: $ENV:ComputerName"
}
Il metodo precedente crea una sessione temporanea e la chiude subito dopo il termine del comando o del blocco di script.
Per lasciare la sessione aperta ed eseguire successivamente un altro comando, è necessario prima creare una sessione remota:
$Session = New-PSSession -ComputerName "RemoteComputerName"
Quindi puoi usare questa sessione ogni volta che invochi comandi sul computer remoto:
Invoke-Command -Session $Session -ScriptBlock {
Write host "Remote Computer Name: $ENV:ComputerName"
}
Invoke-Command -Session $Session -ScriptBlock {
Get-Date
}
Se è necessario utilizzare credenziali diverse, è possibile aggiungerle con il parametro -Credential
:
$Cred = Get-Credential
Invoke-Command -Session $Session -Credential $Cred -ScriptBlock {...}
Avviso di serializzazione remota
Nota:
È importante sapere che il servizio remoto serializza gli oggetti PowerShell sul sistema remoto e li deserializza al termine della sessione remota, ovvero vengono convertiti in XML durante il trasporto e perdono tutti i loro metodi.
$output = Invoke-Command -Session $Session -ScriptBlock {
Get-WmiObject -Class win32_printer
}
$output | Get-Member -MemberType Method
TypeName: Deserialized.System.Management.ManagementObject#root\cimv2\Win32_Printer
Name MemberType Definition
---- ---------- ----------
GetType Method type GetType()
ToString Method string ToString(), string ToString(string format, System.IFormatProvi...
Considerando che hai i metodi sull'oggetto PS regolare:
Get-WmiObject -Class win32_printer | Get-Member -MemberType Method
TypeName: System.Management.ManagementObject#root\cimv2\Win32_Printer
Name MemberType Definition
---- ---------- ----------
CancelAllJobs Method System.Management.ManagementBaseObject CancelAllJobs()
GetSecurityDescriptor Method System.Management.ManagementBaseObject GetSecurityDescriptor()
Pause Method System.Management.ManagementBaseObject Pause()
PrintTestPage Method System.Management.ManagementBaseObject PrintTestPage()
RenamePrinter Method System.Management.ManagementBaseObject RenamePrinter(System.String NewPrinterName)
Reset Method System.Management.ManagementBaseObject Reset()
Resume Method System.Management.ManagementBaseObject Resume()
SetDefaultPrinter Method System.Management.ManagementBaseObject SetDefaultPrinter()
SetPowerState Method System.Management.ManagementBaseObject SetPowerState(System.UInt16 PowerState, System.String Time)
SetSecurityDescriptor Method System.Management.ManagementBaseObject SetSecurityDescriptor(System.Management.ManagementObject#Win32_SecurityDescriptor Descriptor)
Uso di argomenti
Per utilizzare gli argomenti come parametri per il blocco di script remoto, è possibile utilizzare il parametro ArgumentList
di Invoke-Command
oppure utilizzare la sintassi $Using:
Usando ArgumentList
con parametri senza nome (cioè nell'ordine in cui sono passati allo scriptblock):
$servicesToShow = "service1"
$fileName = "C:\temp\servicestatus.csv"
Invoke-Command -Session $session -ArgumentList $servicesToShow,$fileName -ScriptBlock {
Write-Host "Calling script block remotely with $($Args.Count)"
Get-Service -Name $args[0]
Remove-Item -Path $args[1] -ErrorAction SilentlyContinue -Force
}
Utilizzo di ArgumentList
con parametri denominati:
$servicesToShow = "service1"
$fileName = "C:\temp\servicestatus.csv"
Invoke-Command -Session $session -ArgumentList $servicesToShow,$fileName -ScriptBlock {
Param($serviceToShowInRemoteSession,$fileToDelete)
Write-Host "Calling script block remotely with $($Args.Count)"
Get-Service -Name $serviceToShowInRemoteSession
Remove-Item -Path $fileToDelete -ErrorAction SilentlyContinue -Force
}
Utilizzo di $Using:
sintassi:
$servicesToShow = "service1"
$fileName = "C:\temp\servicestatus.csv"
Invoke-Command -Session $session -ScriptBlock {
Get-Service $Using:servicesToShow
Remove-Item -Path $fileName -ErrorAction SilentlyContinue -Force
}
Una best practice per la pulizia automatica delle PSSession
Quando viene creata una sessione remota tramite il cmdlet New-PSsession
, la PSSession persiste fino al termine della sessione corrente di PowerShell. Ciò significa che, per impostazione predefinita, la PSSession
e tutte le risorse associate continueranno ad essere utilizzate fino al termine della sessione corrente di PowerShell.
Più PSSessions
attive possono diventare un problema per le risorse, in particolare per gli script di lunga durata o interconnessi che creano centinaia di PSSessions
in una singola sessione di PowerShell.
È consigliabile rimuovere esplicitamente ciascuna PSSession
dopo averla utilizzata. [1]
Il seguente modello di codice utilizza try-catch-finally
per ottenere quanto sopra, combinando la gestione degli errori con un metodo sicuro per garantire che tutte le PSSessions
create vengano rimosse quando vengono utilizzate:
try
{
$session = New-PSsession -Computername "RemoteMachineName"
Invoke-Command -Session $session -ScriptBlock {write-host "This is running on $ENV:ComputerName"}
}
catch
{
Write-Output "ERROR: $_"
}
finally
{
if ($session)
{
Remove-PSSession $session
}
}
Riferimenti: [1] https://msdn.microsoft.com/en-us/powershell/reference/5.1/microsoft.powershell.core/new-pssession