Powershell Remoting

Summary

In this article i will show you how to use powershell, my favorite command-line shell, in combination with ssh. After this, you can ssh into any machine with any OS and used your favourites cmdlets.

For simplicity, and since i will use two windows machine to show how to use powershell remoting, i will refer to the machine we want to connect to as the window server and the machine from where we want to connect as the windows client.

The steps :

  1. Configure RDP in the windows server
  2. Setup SSH communication with OpenSSH
  3. Install powershell core on both machines
  4. Setup Powershell remoting on both machines
  5. Test PS remoting
  6. Setup SSH to work with public key
  7. Check PS remoting now works without pwd prompt

Configure RDP on the remote machine

At first we will have to go physically to the windows server machine and allow remote desktop on windows. That is super easy we just need to follow the instructions in the official microsoft documentation and enable remote desktop.

Setup SSH communication with OpenSSH

We should install the OpenSSH server and client in both machines for bidirectional communication. In windows machines we can do this by the Optional Features.
On windows 11 :
Start Menu (press Win Key) -> Settings -> System -> Optional Features

After settings this up on the windows server, we should make sure the service (the openssh server) will run everytime the server boots and it will be ready to use. OpenSSH obviously is a windows server so we can go to :
Start Menu (press Win Key) -> Services -> Look for “Open SSH Server” -> Right-Click -> Properties -> Startup type : Automatic

Let’s check the current configuration of our openssh server after installation. This configuration is in [your-root]:\ProgramData\ssh\sshd_config. We should have something like the following :

# This is the sshd server system-wide configuration file.  
# sshd_config(5) for more information.

//...
#Port 22
#AddressFamily any
#ListenAddress 0.0.0.0
#ListenAddress ::

//...
#HostKey __PROGRAMDATA__/ssh/ssh_host_rsa_key
#HostKey __PROGRAMDATA__/ssh/ssh_host_dsa_key
#HostKey __PROGRAMDATA__/ssh/ssh_host_ecdsa_key
#HostKey __PROGRAMDATA__/ssh/ssh_host_ed25519_key
//...

# To disable tunneled clear text passwords, change to no here!
#PasswordAuthentication yes
#PermitEmptyPasswords no

//...
# override default of no subsystems
Subsystem	sftp	sftp-server.exe

On our windows client machine we can test that we can make a connection by running the util “ssh” in the terminal :

> ssh [your-username]@192.168.50.188

Install powershell core

Now, on the client machine let’s install powershell core. For that we can go to the GitHub official repo and search in Releases for the proper asset, taking into account OS, cpu arquitecture and so on… I choosed windows x64 msi format.

We might notice a step where we can enable the powershell remoting. Just leave it for now as we will do this later by the terminal.

Let’s do the same in windows server.

Setup Powershell remoting in both machines

Now, going back to the windows client machine, we would like to use the cmdlet Enter-PSSession with the following syntax :

 Enter-PSSession [-HostName] <string> [-Options <hashtable>] [-Port <int>] [-UserName <string>] [-KeyFilePath
    <string>] [-Subsystem <string>] [-ConnectingTimeout <int>] [-SSHTransport {true}] [<CommonParameters>]

// like so...
Enter-PSSession -HostName 192.168.50.78 -UserName joaoc

However if we run the following command to check the possible syntaxes we will not find the one that we need.

> Get-Help Enter-PSSession

This is because by default in powershell core (at least in the current one 7.4.1) we just have the possibility to connect remotely with WinRM , a alternative to openssh each only works between windows machines. To use Openssh we need to install a module called Microsoft.PowerShell.RemotingTools :

> Install-Module Microsoft.PowerShell.RemotingTools

After this if we run Get-Help Enter-PSSession again we should have the option that we want.

Let’s now try to estabilish a ssh session by powershell :

> PS C:\Users\joaoc> Enter-PSSession -HostName 192.168.50.78 -UserName joaoc
subsystem request failed on channel 0

This error is because we need to configure the Openssh subsystem, or in simple words, the program each the openssh will execute/open hence the ssh communication will be estabilished.

In the windows server we want to run the Enable-SSHRemoting command each is part of the module Microsoft.PowerShell.RemotingTools that we install before, so :

> Enable-SSHRemoting

After this if we go again to the openssh config file C:/ProgramData/ssh/sshd_config we can see that a new subsytem, the powershell application, has added :

//...

# override default of no subsystems
Subsystem       powershell      C:\PROGRA~1\POWERS~1\7\pwsh.exe -SSHS -NoProfile -NoLogo 
Subsystem	sftp	sftp-server.exe

Finally, let’s go to the windows client and try to estabilish a ssh connection :

PS C:\Users\joaoc> Enter-PSSession -HostName 192.168.50.188 -UserName joaoc
joaoc@192.168.50.188's password:
[192.168.50.188]: PS C:\Users\joaoc\Documents> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      7.4.1
PSEdition                      Core
GitCommitId                    7.4.1
OS                             Microsoft Windows 10.0.19045
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

Setup SSH to work with public key in Windows

Althought cool, a bit annoying to have to put the password all the time, we can setup in the context of openssh authentication by public key and avoid having to put the password everytime. What i will explain next will be only for a windows server.

After the installation of openssh client on the windows client we should have a folder : C:\Users\[your-username]\.ssh . Let’s go to this dir and create our pair of keys (private and public) :

> PS C:\Users\joaoc\.ssh> ssh-keygen -t ed25519

// you can click enter when propmpted to choose a file
// so that you use the default location and name

// choose a passphrase
// in test envs empty passphrase is acceptable
// if we choose a passphrase you will have to put it        // everytime when connecting event when using a pubkey

// them you should have something like this
> PS C:\Users\joaoc\.ssh> ls

    Directory: C:\Users\joaoc\.ssh

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a---           09-Mar-24 12:02 PM            355 config
-a---           12-Dec-23  5:12 PM            399 id_ed25519
-a---           12-Dec-23  5:12 PM             93 id_ed25519.pub
-a---           09-Mar-24 12:06 PM           2176 known_hosts

Now, we need to send the public key to our windows server. The choice on the location of the key depends if the user we are log-in as, is a administrator or not. I will show for the case of administrators each i believe is the most common case. For them the public keys go in a file named administrators_authorized_keys that should be in C:/ProgramData/ssh.


Let’s start by passing the public key to the windows server with scp :

> scp id_ed25519.pub joaoc@192.168.50.188:%programdata%/ssh

Let’s ssh into the machine :

> ssh joaoc@192.168.50.188
// in the windows server
> cd %programdata%/ssh

// check that public key is there
> dir

> type id_ed25519.pub >> administrators_authorized_keys

// Now we need to give permissons ! very important !
// we will only give permissons to administrator or system
icacls administrators_authorized_keys /inheritance:r /grant "Administrators:F" /grant "SYSTEM:F"

If we do RDP to the windows machine and check the properties of the file we just created. In the security tab you should see something like this :

Next we need to allow public key authentication. We need to open ssshd_config with notepad or notepad++ using elevated priviligies and change :

//...
# To disable tunneled clear text passwords, change to no here!
PasswordAuthentication yes
//...

We need also to restart the openssh service

So, now on ou windows client machine let’s test. If there is no passphrase (empty passphrase) you should connect immediately, if during the creation of the keys you choose a passphrase you need to always put that.

PS C:\Users\joaoc\.ssh> ssh joaoc@192.168.50.188

// into the windows server
joaoc@DESKTOP-CKJEREI C:\Users\joaoc>

Check PS remoting now works without pwd prompt

Now with using powershell remote :

PS C:\Users\joaoc\.ssh> Enter-PSSession -HostName 192.168.50.188 -UserName joaoc
[192.168.50.188]: PS C:\Users\joaoc\Documents>

Without any prompt. Beautifull ! 🙂

Leave a Reply

Your email address will not be published. Required fields are marked *