Home

Awesome

<p align="center"> <img src="Assets/iconv2-1.png" width="384"/> </p>

Power Remote Desktop

<img src="Assets/prdp-banner.png" width="100%"/>

āš ļø As of August 2024, PowerRemoteDesktop has been rebranded as Arcane and is now available through this official repository. The current repository will no longer be maintained. Please be sure to bookmark the new repository and leave a star if you find it useful!

Welcome to Power Remote Desktop for remote desktop access in pure PowerShell! This module offers a unique solution for remotely controlling one or multiple screens using only PowerShell. Unlike other remote desktop tools that rely on external protocols and software, our module utilizes its own remote desktop protocol.

The module consists of both a client and a server component, both of which are written entirely in PowerShell. Our protocol provides secure, encrypted communication using TLS and offers both challenge-based password authentication and certificate-based authentication.

In addition to providing full mouse and keyboard control over the remote desktop, our module also replicates the mouse cursor icon for the viewer, synchronizes the clipboard between the local and remote systems, and more. Despite the limitations of PowerShell, we have implemented techniques to optimize network traffic and improve the streaming experience, resulting in a smooth and efficient remote desktop experience.

At the time of writing, this is the only known entirely PowerShell-based remote desktop application. We hope you find it useful and we welcome any feedback or suggestions you may have.

Tested on:

Current version: 4.0.0 Stable

Performance

For a better streaming performance and overall experience, we recommend using PowerShell 7 instead of PowerShell 5.

You can install PowerShell 7 for Windows here


Highlighted Features

<img src="Assets/image31.png" width="100%"/>

Setup everything in less than a minute (Fast Setup)

Install-Module -Name PowerRemoteDesktop_Server

Invoke-RemoteDesktopServer -CertificateFile "<certificate_location>"

If you want to avoid using your own certificate and prefer not to go through the process of creating one, you can remove the 'CertificateFile' option and run PowerShell as an administrator instead.

Install-Module -Name PowerRemoteDesktop_Viewer

Invoke-RemoteDesktopViewer -ServerAddress "<ip_address>" -Password "<the_one_displayed_on_server>"

Thats it šŸ˜‰


Detailed Installation and Instructions

There are several ways to use this PowerShell application. The recommended method is to install both the server and viewer components using the PowerShell Gallery. Alternatively, you can install them as modules or import them as scripts manually. Choose the method that best fits your needs and preferences.

Install as a PowerShell Module from PowerShell Gallery (Recommended)

You can install Power Remote Desktop from the PowerShell Gallery, which is similar to Aptitude for Debian or Brew for MacOS. To do so, run the following commands:

Install-Module -Name PowerRemoteDesktop_Server

Install-Module -Name PowerRemoteDesktop_Viewer

AllowPrerelease is mandatory when current version is marked as a Prerelease

When you run the command, you may see the following warning in your command prompt:

Untrusted repository
You are installing the modules from an untrusted repository. If you trust this repository, change its
InstallationPolicy value by running the Set-PSRepository cmdlet. Are you sure you want to install the modules from
'PSGallery'?

Type 'Y' to confirm and proceed with the installation. When the installation is complete, both modules should be available. You can verify this by running the following command:

Get-Module -ListAvailable

Example Output:

PS C:\Users\Phrozen\Desktop> Get-Module -ListAvailable


    Directory: C:\Users\Phrozen\Documents\WindowsPowerShell\Modules


ModuleType Version    Name                                ExportedCommands
---------- -------    ----                                ----------------
Manifest   1.0.0      PowerRemoteDesktop_Server           Invoke-RemoteDesktopServer
Manifest   1.0.0      PowerRemoteDesktop_Viewer           Invoke-RemoteDesktopViewer

<..snip..>

If the modules are not showing up, try running the following commands and then check again:

Import-Module PowerRemoteDesktop_Server

Import-Module PowerRemoteDesktop_Viewer

Install as a PowerShell Module (Manually / Unmanaged)

In order for a module to be available, it must be located in a registered module path. You can view the registered module paths by running the following command:

Write-Output $env:PSModulePath

Example Output:

C:\Users\Phrozen\Documents\WindowsPowerShell\Modules;C:\Program Files\WindowsPowerShell\Modules;C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules

Clone PowerRemoteDesktop repository or download a Github release package.

git clone https://github.com/DarkCoderSc/PowerRemoteDesktop.git

Copy both PowerRemoteDesktop_Viewer and PowerRemoteDesktop_Server folders to desired module path

Example:

C:\Users\<USER>\Documents\WindowsPowerShell\Modules

Both modules should now be available, you can verify using the command:

Get-Module -ListAvailable

Example Output:

PS C:\Users\Phrozen\Desktop> Get-Module -ListAvailable


    Directory: C:\Users\Phrozen\Documents\WindowsPowerShell\Modules


ModuleType Version    Name                                ExportedCommands
---------- -------    ----                                ----------------
Manifest   1.0.0      PowerRemoteDesktop_Server           Invoke-RemoteDesktopServer
Manifest   1.0.0      PowerRemoteDesktop_Viewer           Invoke-RemoteDesktopViewer

<..snip..>

If you don't see them, run the following commands and check back.

Import-Module PowerRemoteDesktop_Server

Import-Module PowerRemoteDesktop_Viewer

Notice: Manifest files are optional (*.psd1) and can be removed.

As a PowerShell Script

It is not mandatory to install this application as a PowerShell module (Even if file extension is *.psm1)

You can also load it as a PowerShell Script. Multiple methods exists including:

Invoking Commands Using:

IEX (Get-Content .\PowerRemoteDesktop_[Server/Viewer].psm1 -Raw)

Loading script from a remote location:

IEX (New-Object Net.WebClient).DownloadString('http://127.0.0.1/PowerRemoteDesktop_[Server/Viewer].psm1')

etc...

Usage

Client

PowerRemoteDesktop_Viewer.psm1 needs to be imported / or installed on local machine.

Available Module Functions

Invoke-RemoteDesktopViewer
Get-TrustedServers
Remove-TrustedServer
Clear-TrustedServers 

Invoke-RemoteDesktopViewer

Create a new remote desktop session with a Power Remote Desktop Server.

āš™ļø Supported Options:
ParameterTypeDefaultDescription
ServerAddressString127.0.0.1Remote server host or address
ServerPortInteger2801Port number for the remote server
SecurePasswordSecureStringNoneSecureString object containing the password used for authenticating with the remote server (recommended)
PasswordStringNonePlain-text password used for authenticating with the remote server (not recommended; use SecurePassword instead))
DisableVerbositySwitchFalseIf specified, the program will suppress verbosity messages
UseTLSv1_3SwitchFalseIf specified, the program will use TLS v1.3 instead of TLS v1.2 for encryption (recommended if both systems support it)
ClipboardEnumBothSpecify the clipboard synchronization mode (options include 'Both', 'Disabled', 'Send', and 'Receive'; see below for more detail)
ImageCompressionQualityInteger (0-100)75JPEG compression level ranging from 0 (lowest quality) to 100 (highest quality)
ResizeSwitchFalseIf specified, the remote desktop will be resized according to the 'ResizeRatio' option
ResizeRatioInteger (30-99)90Used in conjunction with the 'Resize' option, specify the resize ratio as a percentage
AlwaysOnTopSwitchFalseIf specified, the virtual desktop window will be displayed above all other windows
PacketSizeEnumSize9216Specify the network packet size for streams. Choose a size that is appropriate for your network constraints.
BlockSizeEnumSize64Specify the size of the screen grid blocks. Choose a size that is appropriate for the remote screen size and the computer's resources (such as CPU and network capabilities)
LogonUISwitchFalseRequest the server to open the LogonUI/Winlogon desktop instead of the default user desktop (requires SYSTEM privilege in the active session)
Clipboard Mode Enum Properties
ValueDescription
DisabledClipboard synchronization is disabled on both the viewer and server sides
ReceiveOnly incoming clipboard data is allowed
SendOnly outgoing clipboard data is allowed
BothClipboard synchronization is allowed on both the viewer and server sides
PacketSize Mode Enum Properties
ValueDescription
Size10241024 Bytes (1KiB)
Size20482048 Bytes (2KiB)
Size40964096 Bytes (4KiB)
Size81928192 Bytes (8KiB)
Size92169216 Bytes (9KiB)
Size1228812288 Bytes (12KiB)
Size1638416384 Bytes (16KiB)
BlockSize Mode Enum Properties
ValueDescription
Size3232x32
Size6464x64
Size9696x96
Size128128x128
Size256256x256
Size512512x512
āš ļø Important Notices

It is recommended to use SecurePassword instead of a plain-text password, even if the plain-text password is being converted to a SecureString

Example

Open a new remote desktop session to '127.0.0.1:2801' using the password 'urCompl3xP@ssw0rd'

Invoke-RemoteDesktopViewer -ServerAddress "127.0.0.1" -ServerPort 2801 -SecurePassword (ConvertTo-SecureString -String "urCompl3xP@ssw0rd" -AsPlainText -Force)

Enumerate Trusted Servers

When connecting to a new remote server for the first time, the viewer will ask if you want to trust the server's fingerprint. If you select the option to 'Always' trust this fingerprint, it will be saved in the local user registry. You can revoke the trust for this fingerprint at any time using the appropriate function.

Get-TrustedServers

Example output:

PS C:\Users\Phrozen\Desktop\Projects\PowerRemoteDesktop> Get-TrustedServers

Detail                           Fingerprint
------                           -----------
@{FirstSeen=18/01/2022 19:40:24} D9F4637463445D6BB9F3EFBF08E06BE4C27035AF
@{FirstSeen=20/01/2022 15:52:33} 3FCBBFB37CF6A9C225F7F582F14AC4A4181BED53
@{FirstSeen=20/01/2022 16:32:14} EA88AADA402864D1864542F7F2A3C49E56F473B0
@{FirstSeen=21/01/2022 12:24:18} 3441CE337A59FC827466FC954F2530C76A3F8FE4

Permanently Delete a Trusted Server

Remove-TrustedServer -Fingerprint "<target_ingerprint>"

Permanently Delete all Trusted Servers (Purge)

Clear-TrustedServers

Server

PowerRemoteDesktop_Server.psm1 needs to be imported / or installed on local machine.

Available Module Functions

Invoke-RemoteDesktopServer
āš™ļø Supported Options:
ParameterTypeDefaultDescription
ServerAddressString0.0.0.0IP address representing the local machine's IP address
ServerPortInteger2801The port number on which to listen for incoming connections
SecurePasswordSecureStringNoneSecureString object containing the password used for authenticating remote viewers (recommended)
PasswordStringNonePlain-text password used for authenticating remote viewers (not recommended; use SecurePassword instead)
DisableVerbositySwitchFalseIf specified, the program will suppress verbosity messages
UseTLSv1_3SwitchFalseIf specified, the program will use TLS v1.3 instead of TLS v1.2 for encryption (recommended if both systems support it)
ClipboardEnumBothSpecify the clipboard synchronization mode (options include 'Both', 'Disabled', 'Send', and 'Receive'; see below for more detail)
CertificateFileStringNoneA file containing valid certificate information (x509) that includes the private key
EncodedCertificateStringNoneA base64-encoded representation of the entire certificate file, including the private key
ViewOnlySwitchFalseIf specified, the remote viewer will only be able to view the desktop and will not have access to the mouse or keyboard
PreventComputerToSleepSwitchFalseIf specified, this option will prevent the computer from entering sleep mode while the server is active and waiting for new connections
CertificatePasswordSecureStringNoneSpecify the password used to access a password-protected x509 certificate provided by the user
Server Address Examples
ValueDescription
127.0.0.1Only listen for connections from the localhost (usually for debugging purposes)
0.0.0.0Listen for connections on all network interfaces, including the local network and the internet
Clipboard Mode Enum Properties
ValueDescription
DisabledClipboard synchronization is disabled on both the viewer and server sides
ReceiveOnly incoming clipboard data is allowed
SendOnly outgoing clipboard data is allowed
BothClipboard synchronization is allowed on both the viewer and server sides
āš ļø Important Notices
  1. It is recommended to use SecurePassword instead of a plain-text password, even if the plain-text password is being converted to a SecureString.
  2. If you do not specify a custom certificate using 'CertificateFile' or 'EncodedCertificate', a default self-signed certificate will be generated and installed on the local machine (if one does not already exist). This requires administrator privileges. To run the server with a non-privileged account, you must provide your own certificate location.
  3. If you do not specify a SecurePassword or Password, a random, complex password will be generated and displayed in the terminal (this password is temporary).
Examples
Invoke-RemoteDesktopServer -ListenAddress "0.0.0.0" -ListenPort 2801 -SecurePassword (ConvertTo-SecureString -String "urCompl3xP@ssw0rd" -AsPlainText -Force)

Invoke-RemoteDesktopServer -ListenAddress "0.0.0.0" -ListenPort 2801 -SecurePassword (ConvertTo-SecureString -String "urCompl3xP@ssw0rd" -AsPlainText -Force) -CertificateFile "c:\certs\phrozen.p12"

How to capture LogonUI

As of version 4.0.0, it is possible to capture the LogonUI/Winlogon (UAC Prompt, Windows Login Window, CTRL+ALT+DEL, etc.).

However, in order to capture the LogonUI, the server must be run under the context of 'NT AUTHORITY/System' in the current active session.

There are multiple methods for spawning a process as the SYSTEM user in the active session (e.g., PsExec, Process Hacker), but for simplicity I recommend using my PowerRunAsSystem project (available on GitHub and installable through the PowerShell Gallery).

Install-Module -Name PowerRunAsSystem

Then run bellow command as Administrator.

Invoke-InteractiveSystemPowerShell

A new PowerShell terminal should appear on your desktop as NT AUTHORITY/System

If you follow the steps above, a new PowerShell terminal should appear on your desktop running as the 'NT AUTHORITY/System' user.

From this terminal, you can run the Power Remote Desktop server command and enable the 'LogonUI' option for future Power Remote Desktop viewer connections.

It's worth noting that if you don't use your own X509 certificate, you will need administrator privileges to create a new server. However, you can easily create your own X509 certificate using tools such as the OpenSSL command line tool.

Generate your Certificate
openssl req -x509 -sha512 -nodes -days 365 -newkey rsa:4096 -keyout phrozen.key -out phrozen.crt

Then export the new certificate (must include private key).

openssl pkcs12 -export -out phrozen.p12 -inkey phrozen.key -in phrozen.crt
Integrate to server as a file

Use CertificateFile. Example: c:\tlscert\phrozen.crt

Integrate to server as a base64 representation

Encode an existing certificate using PowerShell

[convert]::ToBase64String((Get-Content -path "c:\tlscert\phrozen.crt" -Encoding byte))

or on Linux / Mac systems

base64 -i /tmp/phrozen.p12

You can then pass the output base64 certificate file to parameter EncodedCertificate (One line)

Changelog

11 January 2022 (1.0.1 Beta 2)

12 January 2022 (1.0.2 Beta 3)

12 January 2022 (1.0.3 Beta 4)

Multi Screen Selection

Multi Screen Example

14 January 2022 (1.0.4 Beta 5)

Fingerprint Validation

Server Fingerprint Validation

18 January 2022 (1.0.5 Beta 6)

21 January 2022 (1.0.6)

28 January 2022 (2.0.0)

9 February 2022 (3.0.0)

10 February 2022 (3.1.0)

10 March 2022 (4.0.0)

List of ideas and TODO

šŸŸ¢ = Easy šŸŸ  = Medium šŸ”“ = Hard

Made with ā¤ļø in šŸ‡«šŸ‡·