Hi Everyone, my name is Travis, and I am with the User Experience team here at Microsoft.

Today I’ll be discussing implementing SSH remoting as a Transport for Powershell.

While WinRM is a great transport for Active Directory domains, or domains with a two way forest trust – where WinRM is lacking is in scenarios where there either is no trust between domains, or no domain membership at all. Where there is no domain membership, certificate authentication is your only real choice when it comes to secure Remoting via WinRM.

SSH as a transport changes that because public/private key pairs are used to secure the connection, allowing for encrypted transport of the data sent between the machines – even when an active directory solution has not been implemented. This also means that if you prefer to admin from a *nix installation, you now have a viable transport to manage windows machines from a native *nix remoting implementation.

Newer OS’s include the OpenSSH client natively as a windows capability inbox. The client is enabled by default, however the server is not. To validate the OpenSSH install state, run the following.

Get-WindowsCapability -Online -Name *SSH*



Add the features by piplining get-windowscapability to add-windowscapability. No restart is needed to complete the installation.


On server 2019, be sure to run the latest Cumulative Update, as the error shown below will be thrown due to a known issue that is already resolved in December release patches.


Get-WindowsCapability -Online -Name *SSH* | Add-WindowsCapability -Online


As far as initial configuration is concerned, the service (sshd) must be started, and should be set to automatic as it is not by default. In addition, the firewall rules for SSH must be enabled. This is a TCP connection on port 22.

Start the Service with the below command.

Start-Service sshd

Set the service to automatic startup.

Set-Service -Name sshd -StartupType 'Automatic'


Confirm if the firewall rule is enabled.

Get-NetFirewallRule -Name *ssh*



Set the firewall rule to allow incoming connections if not allowed

Get-NetFirewallRule -Name *ssh* | Set-NetFirewallRule -Enabled True -Direction Inbound -Action Allow


Testing SSH:

Simply use SSH.exe and specify a remote machine name to use implicit credentials against the remote machine to authenticate.


Once the session has been formed, you should simply see a prompt similar to the following:


Simply run the hostname.exe executable to confirm you’re working with the remote machine.


Remoting with Powershell Core

Download and install the latest version of Powershell Core, available on Github.

For the purposes of this Demo, I’m installing the x64 MSI package on both my Windows 10 1809 client, as well as Server 2019 to the default location.

Powershell Core must be configured as a subsystem in $env:ProgramData\ssh\sshd_config. As a note, there is currently a bug in OpenSSH where paths with spaces fail to be recognized as a subsystem. As a work around you can use a symlink to correct the error and point the sshd_config to the symlink location.

For the stable release, use: mklink /D c:\pwsh "C:\Program Files\PowerShell\6"

For the preview release, use: mklink /D c:\pwsh "C:\Program Files\PowerShell\6-preview"

Note that we’re pointing to the symlinked path in the subsystem config below.


After the service configuration is changed, restart the service.

Restart-Service sshd


Powershell Core adds a few new parameters to the Enter-PSsession commandlet, -Hostname, -SSHTransport, -Keyfile, and -Subsystem. Note that you cannot use -computername in combination with -SSHTransport.

An example of Remoting is shown below.



And that's it for today! Thanks for reading, and let us know if you have any comments or questions below!