your123 - stock.adobe.com
How to set up PowerShell remoting over SSH
Microsoft recommends using WinRM to manage Windows machines remotely, but OpenSSH offers other advantages, particularly in organizations that also use Linux systems.
When working in a mixed environment, PowerShell and SSH make for a good remote management combination.
When Microsoft made its PowerShell automation tool open source in 2016, part of the reason was to develop cross-platform compatibility to include macOS and Linux systems. It came as no surprise when the PowerShell team implemented SSH connectivity to enable PowerShell remoting to Linux boxes. SSH is widely considered to be the standard for remoting. Learn how PowerShell remoting over SSH is different from traditional remote management methods in a Windows environment and the basics of how to use remoting over SSH to both Windows and Linux machines.
What is the difference between remoting with SSH and WinRM?
The conventional method for managing Windows remotely is with Windows Remote Management (WinRM), which is Microsoft's version of the Web Services-Management protocol.
To start the WinRM service on Windows, enter the winrm quickconfig command from the Run menu. WinRM is a Windows native service that PowerShell has supported since version 2.0 on Windows 7 and Windows Server 2008.
SSH is the standard remoting tool for Linux. Microsoft added native support on clients running at least Windows 10 1809 and servers running at least Windows Server 2019 with the optional OpenSSH capability installed.
The decision to choose between SSH and WinRM as your remoting protocol of choice is straightforward. Microsoft still recommends WinRM over SSH because of its maturity in the Windows environment and because it supports some additional features that SSH does not, such as remote endpoint configuration and Just Enough Administration (JEA).
However, if you are introducing Windows into a Linux environment where your configuration management tool, such as Ansible, is already configured for SSH on port 22, then it is reasonable to stick with SSH. Ansible supports managing Windows over SSH, although it is considered experimental at this stage.
The prerequisites for PowerShell remoting over SSH are PowerShell 7+ and SSH.
The target computer requires an SSH server, and the source computer requires an SSH client. For Windows, OpenSSH is recommended for both server and client in its respective variant.
How to set up OpenSSH on Windows
The easiest way to set up SSH remoting on Windows requires at least Windows Server 2019 or Windows 10 1809. With either of those OSes and PowerShell 7 running as administrator, you can check for the OpenSSH feature with the following PowerShell command:
Get-WindowsCapability -Online | ?{$_.Name -like 'OpenSSH*'}
Figure 1 shows the SSH client is installed, which is the default. Install the SSH server with the following command:
Add-WindowsCapability -Online -Name "OpenSSH.Server~~~~0.0.1.0"
Lastly, start the SSH service:
Start-Service sshd
You can do the rest of the SSH configuration with Microsoft's RemotingTools PowerShell module. Run the following commands to install that module and its cmdlet to handle some of the SSH configuration:
Install-Module Microsoft.PowerShell.RemotingTools
Enable-SSHRemoting
Run the help for the cmdlet to see all the work this PowerShell command performs related to SSH remoting:
help Enable-SSHRemoting
The last step is to restart the service:
Restart-Service sshd
How to set up OpenSSH for PowerShell on Linux
The steps to install SSH on Linux is different depending on the Linux distribution. For the purposes of this article, we cover the configuration for Ubuntu 22.04, which uses apt, Ubuntu's Advanced Packaging Tool, for package management. If you need to install PowerShell, run the following command:
sudo apt install powershell
You also need the SSH client and server, which typically come preinstalled in Linux. However, if they aren't present, then you can install them with the following commands:
sudo apt install openssh-client
sudo apt install openssh-server
Next, use the same PowerShell module and command used with Windows to install RemotingTools and run the Enable-SSHRemoting cmdlet and restart sshd, the SSH service:
Install-Module Microsoft.PowerShell.RemotingTools
Enable-SSHRemoting
service sshd restart
How to perform PowerShell remoting over SSH
Similar to traditional PowerShell remoting with WinRM, use the Enter-PSSession command to start the interactive session with a remote machine. However, to make the connection over SSH instead of WinRM, use the -HostName parameter instead of the -ComputerName parameter. For example, to connect to a computer over SSH, adapt the following command to your environment:
Enter-PSSession -HostName 10.0.0.10 -UserName User
This is the equivalent of the following Linux command:
ssh [email protected]
The difference is that using the Enter-PSSession PowerShell command uses the PowerShell endpoint.
You can finish the session with the exit command.
PowerShell remoting over SSH does not require named endpoints like WinRM. Instead, you can use an IP address.
Enter-PSSession works from Windows or Linux to a Windows machine or a Linux machine as long as you have met the prerequisites.
How to run scripts with a PowerShell remoting session
Enter-PSSession is great for interactive use, but running a script remotely requires a different approach. You want to use New-PSSession to create a session object and then run commands with the Invoke-Command cmdlet. The New-PSSession command starts a persistent session to the remote machine, while Invoke-Command enables running commands on local and remote machines.
First, generate and configure SSH keys needed to pass a password to the *-PSSession cmdlets. The process to set up SSH keys is outside the scope of this article, but producing them for PowerShell is the same as making them for typical SSH activities.
After creating the SSH keys, create a PowerShell session object:
$session = New-PSSession -HostName 10.0.0.10 -UserName User
Now, you can run commands in that session via Invoke-Command. The following code lists all the running processes on the remote machine.
Invoke-Command -Session $session -ScriptBlock {Get-Process}
When you finish, you can remove the session with the following command:
Remove-PSSession $session
How do I perform advanced PowerShell remoting procedures?
Using sessions opens a lot of options for scripting and remote management. For example, the following code finds all computers with currently running PowerShell:
$processes = $arrayOfComputers | ForEach-Object -ThrottleLimit 10 -Parallel {
$session = New-PSSession -HostName $_ -UserName user
Invoke-Command -Session $session -ScriptBlock {Get-Process}
Remove-PSSession $session
}
$processes | Where-Object {$_.ProcessName -eq 'pwsh'} | Select-Object -ExpandProperty PSComputerName | Select-Object -Unique
The script has no OS checks because Get-Process works the same in Windows and Linux.
In this example script, you can find all computers with a certain file path:
$fileExists = $arrayOfComputers | ForEach-Object -ThrottleLimit 10 -Parallel {
$session = New-PSSession -HostName $_ -UserName user
[pscustomobject]@{
Computer = $_
FileExists = Invoke-Command -Session $session -ScriptBlock {Test-Path '/path/to/test.txt'}
}
Remove-PSSession $session
}
$fileExists | Where-Object {$_.FileExists}
How to troubleshoot PowerShell remoting over SSH issues
If you find yourself unable to connect to a remote device over SSH after checking through the prerequisites, then you can use PowerShell to troubleshoot.
First, check that you have restarted the sshd service with this command:
Restart-Service sshd
Next, test SSH connectivity:
Test-NetConnection -ComputerName 10.0.0.10 -Port 22
Lastly, test to see if SSH is working by using SSH without PowerShell:
ssh [email protected]
Why you should consider SSH remoting with PowerShell
Even if WinRM-based PowerShell remoting is the recommended method for Windows device management, you can see the possibilities that open up with SSH remoting. As long as you don't need remote endpoint configuration or JEA, then SSH works in most scenarios. If you want to have a consistent remoting experience across Windows and Linux, then it's time to get SSH up and running.