What is Invoke-Command Cmdlet in Powershell
Invoke-Command cmdlet has many useful implementations (you can find more examples in the provided link). You can use it to run a command, a set of commands, on a local computer, on a remote computer, on several computers. For remoting you also can check the Cmdlet of “New-PSSession”.
As of Powershell 6.0 you also can connect to remote computer through Secure Shell connection (SSH) with Invoke-Command.
Invoke-Command Powershell Usage Examples
Let’s say you want to run a Powershell file “*.ps1” on a local computer:
Invoke-Command -FilePath c:\scripts\test.ps1
If you want to run a number of Cmdlets in a script block:
Invoke-Command -Scriptblock {
Get-Process
Get-Host
}
If you want to save the script block as a variable and then run it:
$Command = {
Get-Process
Get-Host
}
Invoke-Command -Scriptblock $Command
Sometimes if you get errors you can add Parentheses “()” to the variable:
$Command = ({
Get-Process
Get-Host
})
Invoke-Command -Scriptblock $Command
Invoking Command on remote computer (in most cases you will need credentials to run a command on remote computer):
$Computer = "KitchenComputer001"
$Credential = Get-Credential
Invoke-Command -ComputerName $Computer -Credential $Credential -ScriptBlock {
Get-Host
}
Invoking Command and sending variables to remote computer:
$Computer = "KitchenComputer001"
$Admin = "Administrator"
Invoke-Command -ComputerName $Computer -Credential $Credential -ArgumentList $Credential.UserName,$Admin -ScriptBlock {
Get-LocalUser -Name $args[0]
Get-LocalUser -Name $args[1]
}
*** The first argument always will be “$args[0]” (Arguments are sent as array). Second will be “$args[1]”, third will be “$args[2]”, etc.
Argument can’t be used with quotations “” inside the Script Block, so if you need your argument as a string – better use it in the argument itself or in a variable. For example, you want to add Computer Account “RoomComputer001” to Local Administrators Group of “KitchenComputer001”:
$Computer = "KitchenComputer001"
$ComputerAccount = "RoomComputer001"
Invoke-Command -ComputerName $Computer -Credential $Credential -ArgumentList $ComputerAccount -ScriptBlock {
Add-LocalGroupMember -Group "Administrators" -Member $args[0]
}
*** You can read more in our guide about Add-LocalGroupMember Cmdlet
This will give you “Principal KitchenComputer001 was not found.” Error. Which means, you need to add “$” to the string, so it will be “RoomComputer001$”. You can create another variable and then use THAT variable instead, but it will be much simpler to add to the args[0] parameter with quotes, like
Add-LocalGroupMember -Group "Administrators" -Member "$args[0]$"
This will give you “Principal KitchenComputer001[0]$ was not found.” Error. So, we’ll use the quotes in the argument itself:
$Computer = "KitchenComputer001"
$ComputerAccount = "RoomComputer001"
Invoke-Command -ComputerName $Computer -Credential $Credential -ArgumentList "$ComputerAccount$" -ScriptBlock {
Add-LocalGroupMember -Group "Administrators" -Member $args[0]
}
You can return the output of Invoke-Command to a variable or an array:
$Array = Invoke-Command -ComputerName (Get-Content c:\Computers.txt) -Credential $Credential -ScriptBlock { Get-Process -Name "WmiPrvSE" }
The switch “-ComputerName” gets all the computer names from another Cmdlet “Get-Content” which reads the file “c:\Computers.txt”. Instead of putting Get-Content from Computers.txt into a variable we can set it inside parentheses like: (Get-Content c:\Computers.txt). Then in the script block we want to know all instances of the process “WmiPrvSE” on all the computers. Now “$Array” will contain all the instances of the process on all the computers. A property “PSComputerName” will contain the computer names:
$Array.PSComputerName
Another usage of Invoke-Command is with correlation of New-PSSession:
$RemoteComputer = "KitchenComputer001"
$Credential = Get-Credential
$RemoteSession = New-PSSession –ComputerName $RemoteComputer -Credential $Credential
Invoke-Command –Session $RemoteSession –ScriptBlock {
Get-Host
}
There are times that you need to use a certain Powershell Module (like SCCM / Exchange) and you can execute only on a particular server, so invoking a command is very useful in this case. More uses of a command you can get from the link to Microsoft Docs in the beginning of the article.