Hoe voer je opdrachten of PowerShell-scripts uit op externe computers met Invoke-Command?

Als je ooit hebt geprobeerd om op afstand opdrachten uit te voeren in PowerShell en steeds tegen problemen aanliep, is dat waarschijnlijk erg frustrerend. De cmdlet Invoke-Command is erg handig voor het uitvoeren van scripts of opdrachten op afstand, maar werkt alleen als WinRM (Windows Remote Management) correct is geconfigureerd. Meestal lopen mensen tegen problemen aan omdat WinRM niet is ingeschakeld op de doelmachine, of omdat firewalls inkomende verzoeken blokkeren. Het correct instellen hiervan kan aanvoelen als een kat-en-muisspel, vooral als je niet bekend bent met de exacte opdrachten of de manier om netwerkprofielen of firewallregels aan te passen. Deze handleiding beschrijft hoe je WinRM correct inschakelt, ervoor zorgt dat je netwerk is ingesteld voor beheer op afstand en hoe je vervolgens opdrachten op externe systemen kunt uitvoeren zonder al te veel moeite.

Hoe schakel ik PowerShell-remotebeheer (WinRM) in op Windows?

De WinRM-service inschakelen — een absolute noodzaak om opdrachten op afstand te laten werken

De belangrijkste reden waarom Invoke-Command geen verbinding kan maken? WinRM is niet ingeschakeld of niet geconfigureerd met de juiste netwerkregels. Allereerst moet de WinRM-service actief en geconfigureerd zijn. Om te controleren of WinRM al actief is en luistert, voert u de volgende opdracht uit in PowerShell op de doelmachine:

Get-Service -Name "*WinRM*" | fl WinRM, State Get-Item wsman:\localhost\Listener 

Als het niet geconfigureerd is, geen probleem. Voer op de doelmachine het volgende commando uit:

winrm quickconfig

Deze opdracht doet een aantal dingen: de WinRM-service starten, deze instellen op automatisch starten, een standaardlistener aanmaken en firewall-uitzonderingen toevoegen. Soms Enable-PSRemoting -Forceis het voldoende om de opdracht gewoon als beheerder in PowerShell uit te voeren, vooral als u dit op afstand of via scripts probeert te doen. Houd er rekening mee dat u in sommige configuraties uw netwerkprofiel mogelijk moet aanpassen naar Privé of Domein, omdat PowerShell Remote standaard niet soepel werkt via openbare netwerken.

Korte opmerking: Op sommige machines kunt u problemen ondervinden met netwerkprofielen. Het is een beetje vreemd, maar het wijzigen van het netwerk van Openbaar naar Privé via Instellingen > Netwerk > Ethernet of Wi-Fi > Netwerkprofiel lost de problemen met de machtigingen vaak op. Als de externe verbinding nog steeds niet tot stand komt, kunt u de firewallregels aanpassen of inkomend WinRM-verkeer expliciet toestaan.

Set-NetFirewallRule -Name "WINRM-HTTP-In-TCP" –RemoteAddress Any

Deze regel staat inkomend WinRM-verkeer toe, ongeacht het netwerkadres. Dit is handig als u te maken hebt met meerdere subnetsegmenten of een onorthodoxe netwerkconfiguratie. Onthoud dit, want Windows maakt het soms natuurlijk onnodig ingewikkeld.

Vertrouwde hosts — bij het werken met meerdere werkgroepen of IP-adressen

Als uw systemen zich niet in een domein bevinden of als u verbinding maakt via IP-adres, moet u die externe machines toevoegen aan uw lijst met vertrouwde hosts. Dit is een beetje een kwestie van “veiligheid uit gemak”, maar het is wel nodig. Voer het volgende commando uit:

Set-Item wsman:\localhost\Client\TrustedHosts -Value "192.168.1.201"

Of, als je je roekeloos voelt, sta dan gewoon alles toe:

Set-Item wsman:\localhost\Client\TrustedHosts -Value "*"

Vergeet niet dat u de WinRM-service daarna opnieuw moet starten:

Restart-Service WinRM
Opmerking: Wanneer u meerdere hosts toevoegt, scheidt u hun IP-adressen of namen met komma’s binnen aanhalingstekens, bijvoorbeeld “192.168.1.201, 192.168.1.202”.

Met Invoke-Commands opdrachten uitvoeren op externe computers

Het uitvoeren van één enkel commando — eenvoudig, maar vereist de juiste configuratie.

Zodra WinRM is ingesteld en uw netwerkregels zijn geconfigureerd, hoeft u bij het gebruik van Invoke-Command alleen nog maar de doelmachine en de gewenste opdracht op te geven. Bijvoorbeeld:

Invoke-Command -ComputerName dc01 -ScriptBlock { Get-Service wuauclt }

Hiermee wordt de externe machine met de naam dc01 gevraagd of de Windows Update-service actief is. Verwacht dat de servicestatus wordt weergegeven. In één configuratie werkte dit probleemloos, in een andere kunnen er authenticatieproblemen optreden. Controleer daarom uw machtigingen en netwerkregels.

Handige tip: als je de opdracht onder een ander gebruikersaccount wilt uitvoeren, voeg dan -Credential toe en geef de inloggegevens op:

$cred = Get-Credential Invoke-Command -ComputerName dc01 -Credential $cred -ScriptBlock { Get-NetAdapter }

Dit is meestal handig als uw huidige gebruiker geen deel uitmaakt van de groepen ‘Extern beheer’ of ‘Beheer’ op de doelmachine. Houd er wel rekening mee dat er veel machtigingen bij betrokken zijn en dat PowerShell-beveiligingsbeleid soms bepaalde opdrachten op afstand blokkeert.

Meerdere commando’s of scripts op afstand uitvoeren — ja, dat kan.

Wil je meerdere dingen tegelijk doen? Scheid de opdrachten dan met een puntkomma binnen het ScriptBlock:

Invoke-Command -ComputerName dc01 -ScriptBlock { Get-TimeZone; Set-TimeZone -Name "Central Europe Standard Time" }

En als je ergens een script hebt opgeslagen, bijvoorbeeld C:\PS\CheckStatus.ps1, kun je het op afstand uitvoeren met:

Invoke-Command -ComputerName dc01 -FilePath "C:\PS\CheckStatus.ps1"

Op deze manier hoeft u scripts niet handmatig naar externe systemen te kopiëren en wordt het probleem van een mismatch in het uitvoeringsbeleid als het ware omzeild. Handig voor batchtaken of beheerscripts die u regelmatig uitvoert.

Let op: als uw scripts toegang hebben tot externe bronnen (zoals netwerkshares), kunt u tegen het gevreesde ‘double-hop’-probleem aanlopen. Dit is een beveiligingsprobleem van Windows. Zoek op Google naar oplossingen zoals Kerberos-delegatie of gebruik CredSSP, want anders worden referenties niet doorgegeven aan bronnen van derden.

Opdrachten uitvoeren op meerdere computers tegelijk.

Parallelle commando’s voor een groot aantal servers

Als je een vloot servers beheert, is het uitvoeren van commando’s in serie een lastige klus. Gelukkig maakt Invoke-Command parallelle uitvoering mogelijk. Geef je servers gewoon op, gescheiden door komma’s:

Invoke-Command server1, server2, server3 -ScriptBlock { get-date }

Je kunt de namen ook in een array opslaan voor hergebruik:

$servers = @("server1", "server2", "server3") Invoke-Command -ComputerName $servers -ScriptBlock { get-date }
Of je kunt een lijst uit een tekstbestand gebruiken, waardoor automatisering eenvoudiger wordt:

Invoke-Command -ComputerName (Get-Content c:\ps\servers.txt) -ScriptBlock { Restart-Service spooler }

Als u hostnamen uit Active Directory ophaalt, kunt u met de cmdlet Get-ADComputer filteren op bepaalde systemen:

$computers = (Get-ADComputer -Filter 'OperatingSystem -like "*Windows server*" -and Enabled -eq "true"').Name Invoke-Command -ComputerName $computers -ScriptBlock { Get-EventLog -LogName System -Newest 10 } -ErrorAction SilentlyContinue

En wat als een of meer doelcomputers offline of bezet zijn? De parameter -ErrorAction SilentlyContinue zorgt ervoor dat het script soepel blijft draaien. Bovendien kunt u de variabele PSComputerName in uw ScriptBlock gebruiken om te zien welke machine heeft gereageerd :

$results = Invoke-Command -ComputerName $computers -ScriptBlock { get-date } $results | Select-Object PSComputerName, * 

Permanente PowerShell-verbindingen voor externe toegang — bespaar tijd en moeite

Creëer een sessie die lang blijft hangen.

Als u meerdere opdrachten uitvoert op dezelfde externe machine, is het handig om een ​​sessie actief te houden in plaats van telkens opnieuw verbinding te maken. Zo maakt en gebruikt u een permanente sessie:

$session = New-PSSession -ComputerName Server01, Server02 Invoke-Command -Session $session -ScriptBlock { Get-ComputerInfo | select OsLastBootUpTime }

Als je klaar bent, sluit je de sessie af met:

Remove-PSSession $session

Deze configuratie kan aanzienlijk tijd besparen bij het beheren van meerdere servers, vooral als u veel commando’s uitvoert in een script of geplande taak. Houd er wel rekening mee dat sessies in het geheugen kunnen blijven hangen, dus sluit ze af wanneer ze niet meer nodig zijn. Daarnaast kan het zijn dat sommige configuraties wat extra beveiligingsaanpassingen of beleidswijzigingen vereisen om persistente sessies toe te staan.

Eerlijk gezegd kan het opzetten van PowerShell-beheer op afstand in het begin aanvoelen als een gevecht tegen een machtige baas, maar als het eenmaal lukt, is het ontzettend krachtig. Vergeet niet om de netwerk- en firewallregels te controleren en heb geduld met eventuele eigenaardigheden.