PowerShell Remoting in Multi-Platform Environments using OpenSSH

So in my last post I told you about how I started my journey on learning PowerShell, let’s keep going down that path together. In this post I’m going to introduce PowerShell Remoting in Multi-Platform Environments, specifically using OpenSSH. We’ll discuss WinRM in multi-platform systems in an upcoming post.

Have you ever had to execute a command against one system or a collection of systems? Have you ever wanted a remote shell on a Windows system? Using Remoting you can you can do all of these things, very, very easily.

The Plumbing

So for our first stop, let’s talk about how remoting works. Essentially what’s occurring under the hood is a PowerShell process on one system is sending commands to a PowerShell process on another system then the remote system sends the output back. Easy enough, right? Let’s dig into to how it exchanges information.

The PowerShell processes exchange messaged defined in the PowerShell Remoting Protocol (PSRP). PSRP defines semantics of the communication and types of message being exchanged. Now these messages need a transport layer, for that we have WinRM and OpenSSH. Let’s look at both.

By default, Windows PowerShell systems Remoting connections communicate using WinRM which uses HTTP/S endpoints. WinRM is an implementation of the WS-Management industry standard. WS-Man defines the semantics of the interactions between the systems and data transfer. PowerShell encapsulates its PSRP messages and uses WinRM to transport them between systems.

On Linux systems, well…they don’t communicate with WinRM, by default, so we need something else…that’s where OpenSSH comes in. PowerShell encapsulates it’s inputs and outputs as PSRP messages and it uses SSH to securely exchange the messages between systems.

The PowerShell team has implemented WinRM over HTTP remoting on Linux and already has a port of OpenSSH on Windows. The key idea going forward is…we will have a choice, we can use WinRM (HTTPS) or we can use SSH regardless of OS. For the rest of this post, we’re going to talk remoting over OpenSSH, even on the Windows side of things. We’ll discuss WinRM in multi-platform systems in an upcoming post.

The Installation

For starters, go ahead and install PowerShell Core your systems if you haven’t already, its pretty straightforward check out this link here.

Next, on Windows we need to install OpenSSH and the PowerShell team has developed a Win32 port of OpenSSH. So go check that out here. I’m going to be honest, the installation isn’t easy. But I’m going to let you in on a secret, Darwin Savoy wrote a killer Chocolatey package that does the hard work for you. Check that out here. You’ll want to use the following syntax to install OpenSSH as a service.

choco install openssh -params '"/SSHServerFeature"'

If you’re on Windows verify OpenSSH is up and running

Get-Service -name sshd

Now on Linux, just about every distribution includes an OpenSSH installation their default setup…so we’re not going to cover that here.

The Configuration

Wether it’s Windows or Linux, we need to tell OpenSSH about PowerShell and we can do that with a subsystem configuration.

On a Windows system we’ll need a line like this in SSH daemon configuration file C:\Program Files\OpenSSH\sshd_config. Find the subsystem section and add this line.

Subsystem    powershell c:/program files/powershell/6.0.0-beta.1/powershell.exe -sshs -NoLogo -NoProfile

On a Linux system we’ll need a line like this one in /etc/ssh/sshd_config. Find the subsystem section and add this line.

Subsystem    powershell /usr/bin/powershell -sshs -NoLogo -NoProfileSubsystem

Basically what’s going on here is we’re telling OpenSSH to invoke a PowerShell process when it receives a message from a remote system that’s says it’s going to use the PowerShell subsystem. So SSH is just the conduit for these two PowerShell processes to communicate their inputs and outputs.

When you’re finished editing these files, you’ll want to restart the SSH daemons on your system…Windows or Linux.

On Windows that’s Restart-Service -name sshd on Linux that’s systemctl restart sshd

Now here’s the thing…before you move on…test your SSH connections. You will absolutely go crazy if there’s an issue with your SSH configuration and you try using PowerShell Remoting right away. If there’s an issue, PowerShell will happily swallow OpenSSH’s errors and you’ll get no feedback. Simply grab your favorite SSH client and try to connect to the systems right now and verify you can connect and get a command line. Things will be a lot easier for you before you try to use remoting.

Up next in this series we’ll look at some remoting use cases, specifically using a command line interface, executing commands against remote a remote system and executing commands against a collection of remote systems.