Use PowerShell to create an SSH tunnel for a Remote Desktop Connection (RDP) to another computer with OpenSSH-Server installed

#Use PowerShell to create an SSH tunnel for a Remote Desktop Connection (RDP) to another computer with OpenSSH-Server installed


#Just the code:

Start-Process ssh -ArgumentList "-N -L 127.0.0.3:13389:10.4.0.12:3389 10.4.0.12 -l sshuser" -Verb open
(Read-Host 'Press Enter to continue...')|Out-Null
&mstsc /V:127.0.0.3:13389 /prompt

#The Long Story…

#Remote Desktop Protocol (RDP) is great but it is not very secure. This is one way to make your RDP connections more secure using a Secure Shell (SSH) tunnel.

#Install SSH Server on Windows 10 or Windows 2019

Install Microsoft OpenSSH.Server package from PowerShell and set SSHD service to Automatic

#Use PowerShell to open SSH in a cmd.exe window that will control the SSH tunnel.

Start-Process ssh -ArgumentList "-N -L 127.0.0.3:13389:10.4.0.12:3389 10.4.0.12 -l sshuser" -Verb open

#The commands will pause while you login to the SSH tunnel session. In this example 127.0.0.3:13889 is the tunnel entrance. 10.4.0.12:3389 is the tunnel destination and will most likely be different for you. In my case it is a Microsoft Windows Server 2019 server that I connect to from a Windows 10 Professional client.

#10.4.0.12 is the address of the SSH server and sshuser is an account on the destination machine. The account used doesn’t need additional rights beyond User rights on Windows 10 to create the tunnel but you will need additional rights to connect via RDP.

#Login to SSH tunnel

#Type in the password for sshuser

#The first time you connect to a new SSH host computer you must accept the SSH key that is presented. Type yes if prompted with a message similar to the text below.

The authenticity of host 'servername (10.04.00.02)' can't be established.
ECDSA key fingerprint is SHA256:(<a large string>).
Are you sure you want to continue connecting (yes/no)?

ssh tunnel login screen

#Leave this window open. Minimize if you need to but it needs to stay running for the tunnel traffic to use.

#This will end with a window that looks like it hangs after you login. It is not hung. That window is where the tunnel runs through. Do not close it. Minimize the window and go back to your script. Press Enter to continue…

SSH tunnel active after a successful login win10 server2019

#Go back to the PowerShell window and press Enter to launch mstsc.exe and make a Remote Desktop Connection using the new SSH tunnel.

(Read-Host 'Press Enter to continue...')|Out-Null

setup ssh tunnel rdp powershell win10 server2019

#Launch mstsc.exe with the new loopback IP and made up port number

#Use the & call operator to force PowerShell to treat the string as a command to be executed and run mstsc.exe which is the Windows command to launch the Remote Desktop Services client also know as Microsoft Terminal Services client (mstsc).

&mstsc /V:127.0.0.3:13389 /prompt

rdp ssh tunnel active win10 powershell


#I used code and knowledge from the page linked below to create this but the code I use is modified to combine techniques and concepts shown there when using PowerShell. 

#This site has information on using Putty and Linux to create SSH tunnel connections as well.

Tunnel RDP through SSH & PuTTY

 

 

 

Enabling Remote Desktop Via PowerShell Direct From A Windows 10 Hyper-V Host Machine

#Enabling Remote Desktop Via PowerShell Direct From A Windows 10 Hyper-V Host Machine

#Note: This does not work on Windows 10 Home Edition.

#Just the code:

If (Test-Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server') {Get-Item 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server'|Set-ItemProperty -Name fDenyTSConnections -Value 0 -PassThru|fl}
Get-NetFirewallRule -DisplayGroup "Remote Desktop"|Set-NetFirewallRule -enabled true -PassThru|select Name,DisplayName,Enabled,Profile|ft -a

#The Long Story…

#Yeah so PowerShell Direct doesn’t do everything and neither does PowerShell Remote.  Simply put, PowerShell Direct is a connection to a remote computer initiated with Enter-PSSession -VMName. PowerShell Remote uses WinRM to communicate and is initiated using Enter-PSSession -ComputerName. It is important to know the difference because each way of connecting doesn’t function exactly the same way. You will get errors in PowerShell Direct using commands that require the Background Intelligent Transfer Serviceor BITS, for one. BITS only works in PowerShell Remote.

#Sometimes using Remote Desktop isn’t even enough to do everything but you can do so much more running commands directly. Simple things like using Out-GridView for formatting complex command output needs to be run directly from the machine you are running PowerShell ISE on via a Remote Desktop session and PowerShell ISE. PowerShell Direct and PowerShell Remote sessions are not allowed to call on Out-Gridview at all.

#Note: These commands work in Windows 10 and in PowerShell Remote and PowerShell Direct.

These are the default Remote Desktop settings (Disabled)

#Enable the Remote Desktop Services (also known as RDP and Terminal Services)

#For maximum security only run this and the firewall command like I have shown above under #Just the code:.

If (Test-Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server') {Get-Item 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server'|Set-ItemProperty -Name fDenyTSConnections -Value 0 -PassThru|fl}

#Check configured port number for Remote Desktop Services (RDS). The default incoming port is 3389 unless you change it.

Get-ItemProperty 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-TCP\' -Name PortNumber -Verbose|ft -w #Check default Remote Desktop incoming port

#Open Firewall for Remote Desktop Services (RDS)

#Open the Windows Firewall for Remote Desktop Services.

Get-NetFirewallRule -DisplayGroup "Remote Desktop"|Set-NetFirewallRule -enabled true -PassThru|select Name,DisplayName,Enabled,Profile|ft -a

#Add users to the Remote Desktop Users group

#The default administrator account is automatically added so this is only needed if you have additional accounts to add. You can also add Active Directory domain user accounts and groups using domain\remoteuser credentials after the –Member switch.

Add-LocalGroupMember -Group 'Remote Desktop Users' -Member remoteuser -Verbose #username or domain\username will work

#Disable NLM authentication

#Allow older versions of Windows to connect with weaker authentication by issuing the following command. I would not disable NLM authentication unless you absolutely need to.

If (Get-ItemProperty 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp') {Get-ItemProperty 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp'|Set-ItemProperty -Name UserAuthentication -Value 0 -PassThru|fl} #disable NLM authentication

#I’ve already disabled Remote Assistance so the settings look like the screenshot below for me once NLM authentication is disabled: