IT-professionals werken zelden alleen op onze lokale computer. Met behulp van de PowerShell Invoke-Command cmdlet, hoeven we dat niet te doen! Met deze cmdlet kunnen we naadloos code schrijven alsof we op onze lokale computer werken.
door de functie PowerShell Remoting te gebruiken, is de Invoke-Command
cmdlet een veelgebruikte PowerShell-cmdlet waarmee de gebruiker code in een PSSession kan uitvoeren., Deze PSSession kan er een zijn die eerder is aangemaakt met deNew-PSSession
cmdlet of het kan snel een tijdelijke sessie aanmaken en afbreken.
gerelateerd: PowerShell Remoting: The Ultimate Guide
denk aan Invoke-Command als het PowerShell psexec. Hoewel ze anders worden geïmplementeerd, is het concept hetzelfde. Neem een bit code of commando en voer het “lokaal” op de externe computer.
Voor Invoke-Command
om te kunnen werken moet PowerShell Remoting ingeschakeld en beschikbaar zijn op de externe computer., Standaard, hebben alle Windows Server 2012 R2 of latere machines het samen met de aangewezen firewalluitzonderingen toegelaten. Als je ongelukkig genoeg bent om Server 2008 machines nog te hebben, zijn er meerdere manieren om Remoting in te stellen, maar een eenvoudige manier is door winrm quickconfig
of Enable-PSRemoting
op de remote machine uit te voeren.
om aan te tonen hoe Invoke-Command werkt met een “ad-hoc Commando”, wat betekent dat er geen nieuwe PSSession nodig is om te worden gemaakt, laten we zeggen dat u een externe Windows Server 2012 R2 of een later domein aangesloten computer hebt., Het wordt een beetje rommelig als je aan werkgroepcomputers werkt. Ik open mijn PowerShell console, typ Invoke-Command
en druk op Enter.
PS> Invoke-Commandcmdlet Invoke-Command at command pipeline position 1Supply values for the following parameters:ScriptBlock:
Ik word onmiddellijk gevraagd om een scriptblock op te geven. Het scriptblock is de code die we gaan draaien op de computer op afstand.
zodat we kunnen bewijzen dat de code in het scriptblok wordt uitgevoerd op de externe computer, laten we gewoon het hostname
commando uitvoeren. Dit commando retourneert de hostnaam van de computer waarop het draait., Het draaien van hostname
op mijn lokale computer levert zijn naam op.
PS> hostnameMACWINVM
laten we nu een scriptblok met dezelfde code in een scriptblok doorgeven aan Invoke-Command
. Voordat we dat doen, vergeten we echter een vereiste parameter: ComputerName
. We moeten Invoke-Command
vertellen op welke externe computer dit commando uitgevoerd moet worden.
PS> Invoke-Command -ScriptBlock { hostname } -ComputerName WEBSRV1 WEBSRV1
merk op dat de uitvoer van hostname
nu de naam is van de externe computer WEBSRV1
. Je hebt wat code gedraaid op WEBSRV1., Het draaien van eenvoudige code in een scriptblock en het doorgeven aan een enkele machine op afstand is de makkelijkste toepassing van Invoke-Command
maar het kan zoveel meer doen.
inhoudsopgave
lokale variabelen doorgeven aan Scriptblocks op afstand
u zult geen enkele verwijzing naar aanroepen in een script hebben. Je script zal waarschijnlijk tientallen regels lang zijn, variabelen gedefinieerde plaatsen hebben, functies gedefinieerd in modules enzovoort., Hoewel alleen het omsluiten van een aantal code in een paar krullende beugels kan onschuldig lijken, je bent in feite het veranderen van de hele scope die code wordt uitgevoerd in. Je stuurt die code immers naar een computer op afstand. Die externe computer heeft geen idee van alle lokale code op je machine, behalve wat er in het scriptblock staat.
bijvoorbeeld, misschien heb je een functie met computernaam en een bestandspad parameter. Het doel van deze functie is om één of andere softwareinstallateur op de externe computer in werking te stellen., U kunt de computernaam en het “lokale” bestandspad doorgeven aan het installatieprogramma dat zich al op de externe computer bevindt.
de onderstaande functie lijkt redelijk, toch? Laten we het natrekken.
het mislukt met een obscure foutmelding vanwege mijn gebruik van de Ampersand operator. De code was niet verkeerd, maar het is mislukt omdat $InstallerFilePath
leeg was, ook al gaf je een waarde door met de functieparameter. We kunnen dit testen door de ampersand te vervangen door Write-Host
.,
PS> Install-Stuff -ComputerName websrv1 -InstallerFilePath 'C:\install.exe'Installer path is:PS>
merk op dat de waarde van $InstallerFilePath
niets is. De variabele is niet uitgebreid omdat het niet werd doorgegeven aan de externe machine. Om lokaal gedefinieerde variabelen door te geven aan het scriptblok op afstand, hebben we twee opties; we kunnen de variabelnaam vooraf laten gaan met $using:
binnenin het scriptblok of we kunnen Invoke-Command
parameter ArgumentList
gebruiken. Laten we naar beide kijken.,
de ArgumentList Parameter
een manier om lokale variabelen door te geven aan een scriptblok op afstand is door de Invoke-Command
ArgumentList
parameter te gebruiken. Deze parameter staat je toe om lokale variabelen door te geven aan de parameter en lokale variabele referenties in het scriptblock te vervangen door placeholders.
het doorgeven van de lokale variabelen aan de ArgumentList
parameter is eenvoudig.
Invoke-Command -ComputerName WEBSRV1 -ScriptBlock { & $InstallerFilePath } -ArgumentList $InstallerFilePath
De parameter ArgumentList
is een objectverzameling. Met objectcollecties kunt u één of meer objecten tegelijk doorgeven., In dit geval passeer ik er maar één.
wanneer het commando cmdlet wordt uitgevoerd, neemt het die verzameling en injecteert het vervolgens in het scriptblok en transformeert het in wezen in een array genaamd $args
. Onthoud dat $args -eq ArgumentList
. Op dit punt, zou je verwijzen naar elke index van de collectie net als je zou een array. In ons geval hadden we slechts één element in de collectie ($InstallerFilePath
) dat “vertaald” naar $args
wat de eerste index in die collectie betekent., Echter, als je meer had, zou je ze gebruiken $args
, $args
enzovoort.
bovendien, als u liever betere namen van variabelen aan scriptblock variabelen toewijst, kunt u ook parameters toevoegen aan het scriptblock net als een functie. Een scriptblock is immers slechts een anonieme functie. Om scriptblock parameters te maken, maak je een param block met de naam van de parameter. Eenmaal aangemaakt, refereer dan naar die parameter in het scriptblock zoals hieronder.,
Invoke-Command -ComputerName WEBSRV1 -ScriptBlock { param($foo) & $foo } -ArgumentList $InstallerFilePath
in dit geval worden de elementen in de ArgumentList
collectie in volgorde” toegewezen ” aan de gedefinieerde parameters. De parameternamen doen er niet toe; het is de volgorde die belangrijk is. Invoke-Command
neemt het eerste element in de ArgumentList
collectie, zoek naar de eerste parameter en wijs deze waarden toe, doe hetzelfde voor de tweede, de derde enzovoort.
de $ Using Construct
de $using
construct is een andere populaire manier om lokale variabelen door te geven aan een scriptblok op afstand., Met deze constructie kunt u de bestaande lokale variabelen hergebruiken, maar eenvoudig de variabelnaam vooraf instellen met $using:
. U hoeft zich geen zorgen te maken over een $args
collectie noch over het toevoegen van een parameterblok.
Invoke-Command -ComputerName WEBSRV1 -ScriptBlock { & $using:InstallerFilePath }
De PowerShell $using
construct is een stuk eenvoudiger, maar als je ooit in het leren van Pester komt, zul je zien dat ArgumentList
je vriend zal zijn.,
Invoke-Command en New-PSSession
technisch gezien gaat dit bericht alleen over Invoke-Command, maar om het nut ervan aan te tonen, moeten we ook het New-PSSession
Commando kort aanraken. Herinner eerder dat ik Invoke-Command
kan “ad-hoc” commando ‘ s gebruiken of bestaande sessies gebruiken.
in deze post hebben we net “ad-hoc” commando ‘ s uitgevoerd op externe computers. We zijn bezig met een nieuwe sessie, code uitvoeren en het afbreken., Dit is prima voor eenmalige situaties, maar niet zozeer voor een tijd dat je het uitvoeren van tientallen commando ‘ s op dezelfde computer. In dit geval is het beter om een bestaande PSSession te hergebruiken door er een te maken met New-PSSession
van tevoren.
voordat u opdrachten uitvoert, moet u eerst een PSSession aanmaken met New-PSSession
. We kunnen dit doen door simpelweg $session = New-PSSession -ComputerName WEBSRV1
uit te voeren. Dit maakt een externe sessie op de server en een verwijzing naar die sessie op mijn lokale machine., Op dit moment kan ik mijn ComputerName
referenties vervangen door Session
en point Session
naar mijn opgeslagen $session
variabele.
Invoke-Command -Session $session -ScriptBlock { & $using:InstallerFilePath }
wanneer uitgevoerd, zult u merken dat de prestaties sneller zijn omdat de sessie al is gebouwd. Als het echter voltooid is, is het belangrijk om de open sessie te verwijderen met Remove-PSSession
.
samenvatting
De Invoke-Command PowerShell-cmdlet is een van de meest voorkomende en krachtige cmdlets die er zijn. Het is er een die ik persoonlijk het meest gebruik van bijna allemaal., Het is gebruiksgemak en de mogelijkheid om een code uit te voeren op externe computers is zeer krachtig en is een opdracht die ik aanbevelen leren van boven naar beneden!