In classic Windows PowerShell versions (up to 5.1), you could use only the WinRM protocol (WSMan, port 5985/5986) to access remote computers using PSRemoting. In the newer cross-platform versions of PowerShell Core 7.x and 6.x, you can use SSH for PowerShell remoting between computers. Let’s try to configure PSRemoting over SSH to connect to Windows, Linux, or macOS hosts.
Enable SSH PowerShell Remoting in Windows
Let’s see how to configure an SSH server on the Windows client-side to enable PowerShell Remoting.
First, enable the built-in OpenSSH server on Windows 10 (version 1809 or newer) and Windows Server 2019. Install the SSH server with the following command (in Windows 10 or 11):
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
Also, install the latest PowerShell Core version:
iex "& { $(irm https://aka.ms/install-powershell.ps1) } -UseMSI"
Then enable an automatic startup for the sshd service using the service management PowerShell cmdlets:
Set-Service -Name sshd -StartupType 'Automatic'
Start-Service sshd
Make sure that Windows is now listening on TCP/22 (SSH) port:
Get-NetTCPConnection -State Listen|where {$_.localport -eq '22'}
Allow inbound SSH connections in Windows Defender Firewall:
Enable-NetFirewallRule -Name *OpenSSH-Server*
Then open the C:\ProgramData\ssh\sshd_config configuration file:
notepad $Env:ProgramData\ssh\sshd_config
Enable SSH password authentication by uncommenting the following line:
PasswordAuthentication yes
You can also allow SSH access using keys:
PubkeyAuthentication yes
Add the line below to the file. It will run the pwsh.exe interpreter for remote SSH connections:
Subsystem powershell c:/progra~1/powershell/7/pwsh.exe -sshs -NoLogo
Save the sshd_config file and restart the sshd service:
restart-service sshd
How to Enable PowerShell SSH Remoting on Linux?
Now let’s see how to configure a Linux host for PowerShell Remoting over SSH.
Install PowerShell Core on your Linux distro according to this guide. I use the following commands for my Ubuntu 20.04 host:
$ sudo apt-get update -y
$ wget -q https://packages.microsoft.com/config/ubuntu/$(lsb_release -rs)/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
$ sudo dpkg -i packages-microsoft-prod.deb
$ sudo apt-get update
$ sudo apt-get install powershell -y
Install an OpenSSH server (if not installed):
$ sudo apt install openssh-server
Add the lines below to /etc/ssh/sshd_config:
PasswordAuthentication yes Subsystem powershell /usr/bin/pwsh -sshs -NoLogo
Restart the ssh service:
sudo systemctl restart sshd.service
PSRemoting over SSH with Examples
Now you can connect to a configured Windows or Linux host using PowerShell over SSH. To access remote computers over SSH, the same cmdlets as in WinRM are used:
New-PSSession
Enter-PSSession
– to establish an interactive PowerShell session with a remote hostInvoke-Command
– to run commands or PS1 scripts remotely
By default, these cmdlets are trying to use WinRM to connect to remote computers. To use the SSH transport, you should use other connection options (available in PowerShell Core, so you have to run them from the pwsh.exe
prompt).
The -HostName (instead of –ComputerName) and –UserName (instead of -Credential) options allow to set the computer name and user for the SSH connection. Using the –KeyFilePath parameter, you can specify SSH keys for authentication (optional). You can also use the -SSHTransport parameter to enable SSH transports for PowerShell traffic explicitly
Let’s try to connect to a remote computer interactively from Windows using the built-in SSH client:
Enter-PSSession -HostName 192.168.50.20 -UserName maxbak
To connect, it is enough to confirm an SSH fingerprint of a server and enter the password of the user who is allowed to connect remotely.
You may create multiple persistent PowerShell sessions to remote computers and execute commands on them over SSH:
$session1 = New-PSSession -HostName 192.168.50.20 -UserName maxbak -SSHTransport
$session2 = New-PSSession -HostName 192.168.54.44 -UserName root -SSHTransport
To run a command on multiple computers at once, use the command below:
Invoke-Command -Session $session1, $session2 -ScriptBlock { $PSVersionTable| select OS, PSVersion}| Select-Object PSComputerName, PSVersion, OS
In this example, we ran the command on both a Windows and a Linux computer and displayed the output in the console.
You can specify multiple SSH sessions in the option and authenticate using RSA keys:
$sshConnections = @{HostName="winsrv1"; UserName="woshub\maxbak"; KeyFilePath="c:\users\maxbak\id_rsa" }, @{ HostName="root@ubunsrv1"; KeyFilePath="c:\vault\ubunsrv1_id_rsa" }
New-PSSession -SSHConnection $sshConnections
Key limitations of PowerShell Remoting over SSH:
- PowerShell profiles are not supported;
- In remote sessions with Linux hosts, sudo is not supported (when run, the following error appears:
sudo: a terminal is required to read the password; either use the -S option to read from standard input or configure an askpass helper
); - Just Enough Administration (JEA) is not supported.
As you can see, configuring PowerShell Remoting via SSH is much easier than via WinRM HTTPS. Also, you can use this connection method to connect to computers in a workgroup using PowerShell without adding them to TrustedHost.
PowerShell Remoting over SSH is a safe and simple alternative to WinRM. PSremoting over SSH is supported on any platform (Windows, Linux, macOS), any additional ports to be opened (except TCP/22 SSH), and is easy to configure.