- Export and import to and from Excel with the PowerShell module ImportExcel - Thu, Apr 21 2022
- Getting started with the PSReadLine module for PowerShell - Thu, Feb 24 2022
- SecretsManagement module for PowerShell: Save passwords in PowerShell - Tue, Dec 22 2020
Invoke-Command includes a -Credential parameter that allows us to connect to the remote computer as a different user than whoever is running the session on the local computer. That is useful when you need to connect to a computer with alternate credentials. But if you log onto a user computer as User1 and must connect to 40 computers as Admin1 and another 10 as Admin2, that can be a challenge.
You could run Invoke-Command twice, each time with different credentials, and that would solve the problem. But there is another way that is more useful. Before I discuss that, let’s review the Invoke-Command. When we type the command and let it run against a group of computers, it creates a connection to each computer, runs the code, and then closes the connection to that computer. Overhead is required for the connection attempt, connection setup, and connection tear-down.
An alternate way of connecting would be to build a connection to the computer first and then keep the connection open, allowing for repeated use of the connection multiple times. We call this creating a remote session to each computer. Connecting this way is faster because the overhead involved with building and removing the connection occurs only once. Each subsequent connection over an existing session is speedy because the connection was already open and ready to receive data.
Using remote sessions, we can create connections to groups of computers with different credentials. When we run Invoke-Command, we don’t have to consider how we would log in to each computer because that’s taken care of previously. Invoke-Command uses already assembled sessions, which have been authenticated ahead of time.
Below, I am connecting to four computers in one domain and five in another. I started by adding the server names to variables called $ServersDomainX and $ServersDomainY. I also created credential objects called $AdminX and $AdminY. Once I have servers and credentials stored, I start by creating new sessions to those computers.
$ServersDomainX | ForEach-Object {New-PSSession $_ -Credential $adminX}
$ServersDomainY | ForEach-Object {New-PSSession $_ -Credential $adminY}
Once I have all the sessions created, I save them to a variable called $Sessions.
Get-PSSession | ft -AutoSize
$sessions = Get-PSSession
The $sessions variable is what I will now use in my Invoke-Command statement. I can invoke and call the sessions all at once and not have to worry about authentication because the sessions have already been established and authenticated. It doesn’t matter now if the machines are in various domains or need different credentials.
$results = Invoke-Command -Session $sessions -ScriptBlock {Get-Date} $results | Select PSComputerName, TimeOfDay
Here, we can see that we connected to nine computers in different domains, with no credentials specified in the one Invoke-Command we issued. Notice the time it took for the results to come back. Because there was no overhead in creating sessions, all data came back in less than one second, regardless of the computer’s distance from me.
Subscribe to 4sysops newsletter!
Summary
Make sure you check out the other posts in this series for more tips on how to deal with situations that can cause problems when connecting to remote computers using Invoke-Command. Please use the comments section below to reach out with your questions and ideas.
That's a pretty good tip! Thanks!
Awesome. Thank you for this explanation. Very clear.
Oh that's nice tip, thanks Mike.