PowerShell Remoting
Eseguire comandi su altri computer tramite WinRM (e SSH in PowerShell 7).
Abilitare
Sul computer di destinazione, da console amministratore:
Enable-PSRemoting -Force
Verifica:
Test-WSMan PC01
In un dominio il remoting si abilita comunemente tramite criteri di gruppo. Su una rete in gruppo di lavoro:
Set-Item WSMan:\localhost\Client\TrustedHosts -Value "192.168.1.20" -Force
Usa TrustedHosts solo con host fidati e con attenzione.
Sessione interattiva
Enter-PSSession -ComputerName PC01
Enter-PSSession -ComputerName PC01 -Credential (Get-Credential)
Exit-PSSession
Il prompt cambia in [PC01]: PS>: i comandi vengono eseguiti sul computer remoto.
Comando su uno o più computer
Invoke-Command -ComputerName PC01 -ScriptBlock { Get-Service Spooler }
Invoke-Command -ComputerName PC01, PC02, PC03 -ScriptBlock { Get-Process | Sort-Object CPU -Descending | Select-Object -First 3 }
Invoke-Command -ComputerName (Get-Content .\elenco.txt) -ScriptBlock { hostname }
Il risultato include la proprietà PSComputerName per distinguere l'origine.
Eseguire uno script locale in remoto
Invoke-Command -ComputerName PC01 -FilePath C:\Script\controllo.ps1
Passare variabili locali
$servizio = "Spooler"
Invoke-Command -ComputerName PC01 -ScriptBlock { Restart-Service $using:servizio }
Invoke-Command -ComputerName PC01 -ScriptBlock { param($n) Get-Service $n } -ArgumentList $servizio
Senza $using:, la variabile dentro lo script block non esiste.
Sessioni persistenti
$s = New-PSSession -ComputerName PC01
Invoke-Command -Session $s -ScriptBlock { $x = 42 }
Invoke-Command -Session $s -ScriptBlock { $x }
Get-PSSession
Remove-PSSession $s
Utili per mantenere lo stato tra più comandi.
Copiare file attraverso la sessione
Copy-Item .\file.txt -Destination C:\Temp\ -ToSession $s
Copy-Item C:\Temp\log.txt -Destination .\ -FromSession $s
Parallelismo
Invoke-Command -ComputerName PC01, PC02, PC03 -ScriptBlock { Get-Date } -ThrottleLimit 16
Invoke-Command -ComputerName PC01, PC02 -ScriptBlock { Start-Sleep 60 } -AsJob
Get-Job | Receive-Job
Credenziali
$cred = Get-Credential
Invoke-Command -ComputerName PC01 -Credential $cred -ScriptBlock { whoami }
Il problema del "secondo salto"
Da una sessione remota non puoi, per impostazione predefinita, accedere ad altre risorse di rete con le tue credenziali (ad esempio una condivisione su un terzo server). Soluzioni: usare credenziali esplicite, CredSSP (con cautela) o la delega vincolata.
Remoting via SSH (PowerShell 7)
Enter-PSSession -HostName server -UserName michele
Enter-PSSession -HostName server -UserName michele -KeyFilePath ~/.ssh/id_ed25519
Invoke-Command -HostName server -UserName michele -ScriptBlock { uname -a }
Funziona anche tra Windows e Linux, a patto di avere un server SSH con il sottosistema PowerShell configurato.
Sicurezza
- WinRM usa HTTP sulla porta 5985 (traffico cifrato a livello applicativo con Kerberos/NTLM in dominio) e HTTPS sulla 5986.
- Limita chi può connettersi:
Set-PSSessionConfiguration -ShowSecurityDescriptorUI. - Prediligi gli account di dominio e i gruppi dedicati, non l'amministratore locale condiviso.
- Per ridurre i privilegi usa JEA (Just Enough Administration).
Disattivare
Disable-PSRemoting -Force