PowerShell Remoting in Multi-Platform Environments – Use Cases

In our previous post we discussed how to implement OpenSSH (the plumbing) as the transport layer for PowerShell remoting. In this post, we’re going to leverage that configuration and look at some common remoting use cases. This is one of the core things I use everyday when I work with PowerShell. Remoting gives me the ability to administer scale up and administer large collections of systems. So like I said in my very first post about my PowerShell journey, it’s become a part of my every day life and techniques like this are at the core of how I use PowerShell. So let’s get started…

We’re going to look at the following

  • Entering a remote command line interface on a server
  • Using sessions
  • Executing commands against one remote system
  • Executing commands on a collection of remote systems

This is going to be awesomeness…Yep, I said awesomeness, when I’m finished you’ll agree that’s about the only way to describe this.

I do want to point out that we’re using Beta software here, things change. The version of PowerShell I’m using here is Version 6 Beta 2.

Remote Command Line Interface

Up first, let’s cover the simplest remoting case, where we use remoting to get a command line interface to a remote system.

Nothing special here, simple syntax, but the seasoned PowerShell remoting pro will notice that we’re using a new parameter here -HostName. Normally on Windows PowerShell you have the -ComputerName parameter. Now, I don’t know exactly why this is different, but perhaps the PowerShell team needed a way to differentiate between OpenSSH and WinRM based remoting. Further, Enter-PSSession now has a new parameter -SSHTransport which at the moment doesn’t seem to do much since remoting cmdlets currently use OpenSSH by default. But if you read the code comments here, it looks like WinRM will be the default and we can use this switch parameter to specify SSH as the transport.

Once we execute this command, you’ll have a command prompt to the system that passed as a parameter to -HostName. The prompt below indicates you’re on a remote system by putting the server name you’re connected to in square brackets then your normal PowerShell prompt. That’s it, you now have a remote shell. Time to get some work done on that server, eh? Want to get out of the session, just type exit.

Using Sessions

So, in PowerShell, when you exit from a remoting session your session goes away. So any work, variables or program state you had will disappear. But what if we wanted to keep our session’s state, log out and log back into that session again? We can leverage sessions to help us persist our remote sessions. We can create a session connect and disconnect from it at will. So let’s check that out.

We create a new session by calling New-PSSession. This will start up the remoting session just like we did with Enter-PSSession, via SSH, but we won’t attach to the remote terminal. The output we do get from New-PSSession shows us the details of the session created. We use Get-PSSession to get a list of all current sessions.

We can connect to an existing session with Enter-PSSession. If there are multiple entries in your session list…just use the correct Id from the session list to identify the session you want to connect to.
Now, when you exit from this session with the exit command, your session will persist. Let’s use Get-PSSession to see.
Cool, our session is still there, let’s reuse it. This time we’re going to assign it to a variable this time. This will keep our command line syntax simple in the upcoming examples.

Executing Commands Against One Remote System

We can use PowerShell remoting to execute a command against a remote system, so let’s look at the simplest case…just one command. Here you can see, we’re using the Invoke-Command cmdlet to execute the Get-Process command on the remote system and it’s output returns to our console. Here we have the top 5 processes by CPU on the remote system.

Executing Commands Against a Collection of Remote Systems

Now, let’s add one more session to our list of sessions. With a new session to server2.
New-PSSession just returns the session created, so let’s get a list of all of the sessions with Get-PSSession. There you can see our two remoting sessions are currently opened the new session has a new Id.
This time, let’s take both our sessions and save them to a variable. We’re going to reuse $s.
Now to the amazing part…let’s run a command against a collection of remote systems.
This example brings up a very interesting point in PowerShell remoting, everything inside the curly braces of the Invoke-Command call happens on the remote system. This means, all the sorting and processing is remote, the remote systems deal with all the computational aspects and less data has to traverse the network. There’s a deeper topic of serialized objects we’ll cover in a later post. Now the output from these systems comes back to your console as fast as it comes back, so there’s really no order here. So you might get a list of data that’s all commingled. But we can control that by sorting locally. Let’s look at that.
Now, let’s say you want to get the top 5 processes across all the systems in your sessions list, easy enough.

We move the sorting to the pipeline on our local system, notice the Invoke-Command call is going to return the entire process list from all machines, then it will sort the data locally and output to the local console. So you can see in this list here we have the top 5 processes across our two systems. Imagine you had a web farm of servers and you needed to chase down a bad process fast, this would be useful, right?

When we’re all finished, you’ll want to clean up your sessions. We can do that a by passing the $s variable into Remove-PSSession

And that’s it, so like I said in my very first post about my PowerShell journey, it’s become a part of my every day life and techniques like this are at the core of how I use PowerShell.

2 thoughts on “PowerShell Remoting in Multi-Platform Environments – Use Cases

  1. Jeff Hicks

    I do not see the -Hostname parameter for Enter-PSSession. Are you running this on Windows or Linux? What version of PowerShell 6? All of this is such a moving target that it would help to specify what version you are running.

    Reply
    1. Anthony Nocentino

      Hi Jeff, I think this is a case where the help doesn’t sync up with what’s implemented. Do a Enter-PSSession -(double-tab) and check out the available parameters. But Excellent point about it being a moving target, I’ll update the post with version information.

      Reply

Leave a Reply

Your email address will not be published. Required fields are marked *