Implementing Cross-Platform PowerShell Remoting via SSH Transport
Learn how to configure PowerShell 7 to use SSH as a transport layer, enabling seamless remoting across Windows, Linux, and macOS without the complexities of WinRM.
13 Jul 2025, 19:58 UTC

The Problem: WinRM Limitations in Heterogeneous Environments
Traditional PowerShell remoting relies on Windows Remote Management (WinRM), which is difficult to configure across firewalls and fundamentally incompatible with Linux and macOS. For engineers managing a mix of Windows and Unix-like systems, WinRM creates a fragmented management experience where different protocols are required for different OS targets.
The solution is using SSH (Secure Shell) as the transport layer for PowerShell 7. By configuring the PowerShell subsystem on the target machine, you can use Enter-PSSession and Invoke-Command across Windows, Linux, and macOS using a single, industry-standard encrypted protocol.
Configuring the PowerShell SSH Subsystem
To enable SSH remoting, the target machine must have an SSH server installed and configured to launch PowerShell instead of a standard shell (like bash or cmd) when requested by a PowerShell client.
Target Configuration (Linux/macOS)
On the target Linux or macOS machine, ensure pwsh is installed. You must modify the SSH daemon configuration file (typically /etc/ssh/sshd_config) to define the PowerShell subsystem. This tells the SSH server how to handle the specific request from a PowerShell client.
# Add this line to /etc/ssh/sshd_config
Subsystem powershell /usr/bin/pwsh -sshs -NoLogo -NoProfile
After saving the file, restart the SSH service (e.g., sudo systemctl restart ssh) to apply the changes.
Target Configuration (Windows)
On Windows, install the OpenSSH Server capability via PowerShell (Run as Administrator):
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
Then, edit C:\ProgramData\ssh\sshd_config and add the subsystem definition. Ensure the path points to your PowerShell 7 executable:
Subsystem powershell C:\Program Files\PowerShell\7\pwsh.exe -sshs -NoLogo -NoProfile
Restart the sshd service via Restart-Service sshd.
Executing Remote Commands
Once the subsystem is configured, the client machine (which must be running PowerShell 7+) can connect using the -HostName parameter instead of -ComputerName. The -HostName parameter signals PowerShell to use SSH transport rather than WinRM.
Example: Public Key Authentication
Public key authentication is the recommended method for automation to avoid interactive password prompts. This example assumes your public key is already present in the target's authorized_keys file.
# Run on the local client machine
$target = "linux-srv-01.internal"
$keyPath = "C:\Users\Admin\.ssh\id_rsa"
# Execute a block of code on the remote target
Invoke-Command -HostName $target -UserName "sysadmin" -KeyFilePath $keyPath -ScriptBlock {
Get-Process | Sort-Object CPU -Descending | Select-Object -First 5
}
Example: Implicit Remoting (Proxying)
You can import a module from a remote SSH session to your local session. This creates "proxy functions" that look local but execute on the remote target.
# Create a session
$session = New-PSSession -HostName "win-srv-02.internal" -UserName "admin"
# Import a module from the remote session
Import-Module -PSSession $session -Name Microsoft.PowerShell.Management
# This call executes on the remote Windows server, not locally
Get-Service -Name "spooler"
Operational Limits and Common Pitfalls
The "Double-Hop" Problem
SSH remoting does not natively support CredSSP (Credential Security Support Provider), which WinRM uses for double-hop delegation. If you connect to Server A via SSH and then try to access a file share on Server B using the same credentials, the request will fail. To resolve this, you must use SSH Agent Forwarding or pass explicit credentials to the second hop.
Subsystem Negotiation Failures
If you receive a "subsystem request failed" error, it almost always indicates a path mismatch in the sshd_config file. Verify that the path to pwsh is absolute and correct for the target OS. On Windows, ensure the sshd service has permissions to execute the binary.
Performance Overhead
Because SSH encrypts every packet, interactive sessions (Enter-PSSession) may feel slower than WinRM on high-latency networks. For bulk operations, prefer Invoke-Command to minimize the number of round-trips.
Verification and Diagnostics
To verify the connection is functional and using the correct version, run the following check:
# Verify connectivity and version
Invoke-Command -HostName <target> -UserName <user> -ScriptBlock { $PSVersionTable.PSVersion }
If the command fails, perform these diagnostic steps:
- Network: Run
Test-NetConnection -ComputerName <target> -Port 22to ensure the SSH port is open. - Logs (Linux): Check
/var/log/auth.logfor "subsystem" request errors. - Logs (Windows): Check Event Viewer under
Applications and Services Logs > OpenSSH.
Rollback
To remove SSH remoting capabilities, remove the Subsystem powershell line from the sshd_config file on the target machine and restart the SSH service. This prevents PowerShell clients from initiating the subsystem while leaving standard SSH shell access intact.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.