Chapter 14Lesson 04~180 minutes

PowerShell Remoting over SSH Across Platforms

Configure the mental model for cross-platform PowerShell remoting over SSH: OpenSSH transport, PowerShell subsystem, host/user keys, HostName sessions, and remote OS differences.

Cross-platformSSHOpenSSHPSRP

Learning objectives

  • Explain how PSRP over SSH differs from WSMan transport.
  • Verify PowerShell, SSH client/server prerequisites and the actual pwsh path.
  • Understand the sshd PowerShell subsystem and privileged configuration boundary.
  • Explain host-key and user-key authentication concepts.
  • Use New-PSSession/Enter-PSSession/Invoke-Command SSH parameter sets.
  • Design a safe loopback/VM lab without weakening host security.

1. SSH changes the transport, not the PowerShell remoting model

PowerShell remoting over SSH still uses the PowerShell remoting model and PSRP behavior you learned in Lesson 1. What changes is the transport and authentication stack: OpenSSH accepts the connection and starts PowerShell as an SSH subsystem.

WSMan pathSSH path
Supported current path: Windows-to-WindowsSupported current path: Windows, Linux, and macOS when PowerShell and OpenSSH are configured
WinRM/WSMan listener and PowerShell session configurationsOpenSSH sshd plus a powershell subsystem entry
Kerberos/Negotiate/other WSMan auth mechanismsSSH authentication mechanisms such as public keys/password as configured by sshd
Supports richer WSMan endpoint/JEA hostingCurrent Microsoft docs say SSH remoting does not support the same remote endpoint configuration/JEA hosting model

2. Verify requirements before editing sshd_config

Microsoft’s current PowerShell 7.6 guidance requires PowerShell 6+ and SSH on both sides. The remote SSH server must define a PowerShell subsystem. The exact pwsh path depends on the installation, so discover it rather than copying an old hard-coded path blindly.

$pwsh = Get-Command pwsh -CommandType Application -ErrorAction Stop
$ssh  = Get-Command ssh -CommandType Application -ErrorAction SilentlyContinue

[pscustomobject]@{
    PowerShell = $pwsh.Source
    SSHClient  = $ssh.Source
    PSVersion  = $PSVersionTable.PSVersion.ToString()
    Platform   = if ($IsWindows) {'Windows'} elseif ($IsLinux) {'Linux'} else {'macOS/Other'}
}

3. sshd must know how to start PowerShell for PSRP

The server’s sshd_config needs a Subsystem powershell ... -sshs entry. Microsoft documents platform-specific paths such as a Windows pwsh.exe path, /usr/bin/pwsh on common Linux installs, and /usr/local/bin/pwsh on common macOS installs—but installation paths can vary.

# Configuration examples only -- do not paste until you have verified Get-Command pwsh.
# Windows sshd_config concept:
# Subsystem powershell C:/path/to/pwsh.exe -sshs

# Linux/macOS sshd_config concept:
# Subsystem powershell /verified/path/to/pwsh -sshs -NoLogo

Editing sshd configuration and restarting the SSH service are privileged operations. Do them only on an authorized lab/managed host and keep a recovery path in case the SSH configuration becomes invalid.

4. Host keys answer “which SSH server am I talking to?”

An SSH host key identifies the server. The first connection normally asks you to verify its fingerprint before recording it in known_hosts. Do not train yourself to auto-accept every new host key in production automation. A changed host key can mean a legitimate rebuild—or impersonation.

For managed fleets, distribute/validate known host fingerprints through an approved mechanism rather than suppressing verification.

5. User keys authenticate the client without embedding a password

Public-key authentication uses a private key held by the client and a corresponding public key authorized on the server. Protect private keys with filesystem permissions and, where practical, passphrases/agents or an enterprise credential system. A key file is a credential even though it is not a password.

# Inspect available SSH parameter sets and parameters in this PowerShell build.
(Get-Command New-PSSession).ParameterSets |
    Where-Object Name -like 'SSH*' |
    Select-Object Name,@{n='Parameters';e={$_.Parameters.Name -join ', '}}

6. New-PSSession -HostName creates an SSH-transport PSSession

# Example: authorized SSH-remoting target.
$session = New-PSSession -HostName 'linux01.example.test' -UserName 'academy'
try {
    Invoke-Command -Session $session -ScriptBlock {
        [pscustomobject]@{
            Host     = [System.Net.Dns]::GetHostName()
            Platform = [System.Runtime.InteropServices.RuntimeInformation]::OSDescription
            Version  = $PSVersionTable.PSVersion.ToString()
        }
    }
}
finally {
    Remove-PSSession $session
}

For key authentication, use the SSH parameter set’s -KeyFilePath where appropriate rather than putting key material into the script.

7. Enter-PSSession and Invoke-Command also have SSH parameter sets

# Interactive diagnosis:
# Enter-PSSession -HostName 'linux01.example.test' -UserName 'academy'

# One-off structured command:
Invoke-Command -HostName 'linux01.example.test' -UserName 'academy' -ScriptBlock {
    [pscustomobject]@{
        Home      = $HOME
        Separator = [System.IO.Path]::DirectorySeparatorChar
        Commands  = @('git','docker','kubectl') | ForEach-Object {
            [pscustomobject]@{ Name=$_; Exists=[bool](Get-Command $_ -ErrorAction SilentlyContinue) }
        }
    }
}

8. PSRP does not erase operating-system differences

A Windows client can SSH-remotely execute PowerShell on Linux, but that remote process still has Linux paths, users, permissions, services, native commands, modules, case sensitivity, and environment conventions. Cross-platform remoting gives you a common orchestration language—not identical target systems.

Invoke-Command -Session $session -ScriptBlock {
    [pscustomobject]@{
        IsWindows = $IsWindows
        IsLinux   = $IsLinux
        IsMacOS   = $IsMacOS
        Home      = $HOME
        Temp      = [System.IO.Path]::GetTempPath()
        ShellPath = (Get-Command pwsh).Source
    }
}

9. Single-machine lab option: SSH back to the same host

Microsoft’s SSH-remoting documentation explicitly uses a loopback-style test as a simple validation path. If your machine already runs an authorized SSH server with a PowerShell subsystem, you can connect back to itself. This still requires real SSH server configuration, host-key trust, and credentials.

# Capability inspection first -- no configuration changes.
$sshServerHints = [pscustomobject]@{
    SSHClient = [bool](Get-Command ssh -ErrorAction SilentlyContinue)
    PSSessionSSHParameters = @((Get-Command New-PSSession).ParameterSets.Name) -join ', '
    Pwsh = (Get-Command pwsh).Source
}
$sshServerHints

# Only after configuring/authorizing sshd + PowerShell subsystem:
# $s = New-PSSession -HostName 'localhost' -UserName '<your-lab-user>'
# Invoke-Command -Session $s -ScriptBlock { $PSVersionTable }
# Remove-PSSession $s

10. Use a VM/container only if it really runs sshd and PowerShell

A container is not automatically a remoting target. To use one for this lab it must run an SSH server, have a PowerShell executable, expose the SSH port, define the PowerShell subsystem, and have a valid authentication path. A small VM is often easier to understand because it behaves more like a host.

If you cannot provide those prerequisites safely, keep the lesson inspect-only and practice the session/output patterns with a prepared organizational lab instead of weakening your workstation’s SSH configuration.

11. Troubleshoot SSH before blaming PSRP

  1. Can the hostname resolve and TCP 22 (or your chosen SSH port) connect?
  2. Can the native ssh client authenticate and validate the host key?
  3. Does sshd accept the user/key policy?
  4. Does the powershell subsystem exist in the server configuration?
  5. Does the subsystem path actually start the intended pwsh?
  6. Only then investigate the PowerShell remote command/session behavior.

12. Verification checklist

  • You can explain what remains PSRP and what changes when using SSH.
  • You verify PowerShell/SSH installation and the actual pwsh path.
  • You understand the sshd PowerShell subsystem role.
  • You treat host keys as server identity evidence.
  • You protect private keys as credentials.
  • You use HostName/UserName/KeyFilePath parameter sets where appropriate.
  • You expect remote platform differences even though the orchestration language is PowerShell.

13. Knowledge check

Question 1. What is the role of the SSH powershell subsystem entry?

Question 2. Does SSH remoting make Linux paths behave like Windows paths?

Question 3. Why verify a host key?

Question 4. Which New-PSSession parameter selects the SSH transport path?

Question 5. Does current SSH remoting provide the same endpoint/JEA hosting model as WSMan?

14. Summary and next bridge

SSH gives PowerShell a supported cross-platform remoting transport while preserving the PSRP/session/serialization model. The transport does not normalize target operating systems, and SSH server/key configuration remains its own security discipline. Lesson 5 now scales the same ideas to fleets where concurrency, partial failure, retries, credentials, and tool choice become the dominant engineering concerns.

15. Authoritative references

Keep the academy open

Support free, practical DevOps education.

Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.

Ethereum / ERC-20
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0 Send only Ethereum/ERC-20 compatible assets to this address.