Power Remote Desktop is a fully functional Remote Desktop Application entirely coded in PowerShell.
It doesn't rely on any existing Remote Desktop Application or Protocol to function. A serious advantage of this application is its nature (PowerShell) and its ease of use and installation.
This project demonstrate why PowerShell contains the word Power. It is unfortunately often an underestimated programming language that is not only resumed to running commands or being a more fancy replacement to the old Windows command-line interpreter (cmd).
Tested on:
- Windows 10 - PowerShell Version: 5.1.19041.1320
- Windows 11 - PowerShell Version: 5.1.22000.282
Current version: 2.0 Stable
Highlighted Features
demo.mp4
- Remote Desktop Streaming with support of HDPI and Scaling.
- Remote Control: Mouse (Moves, Clicks, Wheel) and Key Strokes (Keyboard)
- Secure: Network traffic is encrypted using TLSv1.2 or 1.3. Access to server is granted via a challenge-based authentication mechanism (using user defined complex password).
- Network traffic encryption is using whether a default X509 Certificate (Requires Administrator) or your custom X509 Certificate.
- Server certificate fingerprint validation supported and optionally persistent between sessions.
- Clipboard text synchronization between Viewer and Server.
- Mouse cursor icon state is synchronized between Viewer (Virtual Desktop) and Server.
- Multi-Screen (Monitor) support. If remote computer have more than one desktop screen, you can choose which desktop screen to capture.
- View Only mode for demonstration. You can disable remote control abilities and just show your screen to remote peer.
- Session concurrency. Multiple viewers can connect to a single server at the same time.
Setup everything in less than a minute (Fast Setup)
Install-Module -Name PowerRemoteDesktop_Server Invoke-RemoteDesktopServer -CertificateFile "<certificate_location>"
If you are even more lazy and want to avoid using your own certificate, remove CertificateFile
option but you will need to run PowerShell as Administrator.
Install-Module -Name PowerRemoteDesktop_Viewer Invoke-RemoteDesktopViewer -ServerAddress "<ip_address>" -Password "<the_one_displayed_on_server>"
Thats it
Detailed Installation and Instructions
You will find multiple ways to use this PowerShell Applications. Recommended method would be to install both Server and Viewer using the PowerShell Gallery but you can also do it manually as an installed module or imported script.
Install as a PowerShell Module from PowerShell Gallery (Recommended)
You can install Power Remote Desktop from PowerShell Gallery. See PowerShell Gallery as the 'equivalent' of Aptitude for Debian or Brew for MacOS.
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
Your command prompt will show the following warning:
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'?
Answer Y
to proceed installation.
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
Install as a PowerShell Module (Manually / Unmanaged)
To be available, the module must first be present in a registered module path.
You can list module paths with 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:
Parameter | Type | Default | Description |
---|---|---|---|
ServerAddress | String | 127.0.0.1 | Remote server host/address |
ServerPort | Integer | 2801 | Remote server port |
SecurePassword | SecureString | None | SecureString object containing password used to authenticate with remote server (Recommended) |
Password | String | None | Plain-Text Password used to authenticate with remote server (Not recommended, use SecurePassword instead) |
DisableVerbosity | Switch | False | If present, program wont show verbosity messages |
UseTLSv1_3 | Switch | False | If present, TLS v1.3 will be used instead of TLS v1.2 (Recommended if applicable to both systems) |
Clipboard | Enum | Both | Define clipboard synchronization mode (Both , Disabled , Send , Receive ) see bellow for more detail |
ImageCompressionQuality | Integer (0-100) | 100 | JPEG Compression level from 0 to 100. 0 = Lowest quality, 100 = Highest quality. |
Resize | Switch | False | If present, remote desktop will get resized accordingly with ResizeRatio option. |
ResizeRatio | Integer (30-99) | 90 | Used with Resize option, define the resize ratio in percentage. |
AlwaysOnTop | Switch | False | If present, virtual desktop form will be above all other window's |
Clipboard Mode Enum Properties
Value | Description |
---|---|
Disabled | Clipboard synchronization is disabled in both side |
Receive | Only incomming clipboard is allowed |
Send | Only outgoing clipboard is allowed |
Both | Clipboard synchronization is allowed on both side |
⚠️ Important Notices
Prefer using SecurePassword
over plain-text password even if a plain-text password is getting converted to SecureString
anyway.
Example
Open a new remote desktop session to 127.0.0.1:2801
with password [email protected]
Invoke-RemoteDesktopViewer -ServerAddress "127.0.0.1" -ServerPort 2801 -SecurePassword (ConvertTo-SecureString -String "[email protected]" -AsPlainText -Force)
Enumerate Trusted Servers
When a fingerprint is met for the first time, viewer will ask you if you want to trust this new remote server fingerprint.
When you choose the [A] Always
option, this fingerprint will be saved to local user registry. If you change your mind, you can revoke trsuted fingerprint at any time using dedicated functions.
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)
Server
PowerRemoteDesktop_Server.psm1
needs to be imported / or installed on local machine.
Available Module Functions
Invoke-RemoteDesktopServer
⚙️ Supported Options:
Parameter | Type | Default | Description |
---|---|---|---|
ServerAddress | String | 0.0.0.0 | IP Address that represents the local IP address |
ServerPort | Integer | 2801 | The port on which to listen for incoming connection |
SecurePassword | SecureString | None | SecureString object containing password used to authenticate remote viewer (Recommended) |
Password | String | None | Plain-Text Password used to authenticate remote viewer (Not recommended, use SecurePassword instead) |
DisableVerbosity | Switch | False | If present, program wont show verbosity messages |
UseTLSv1_3 | Switch | False | If present, TLS v1.3 will be used instead of TLS v1.2 (Recommended if applicable to both systems) |
Clipboard | Enum | Both | Define clipboard synchronization mode (Both , Disabled , Send , Receive ) see bellow for more detail |
CertificateFile | String | None | A file containing valid certificate information (x509), must include the private key |
EncodedCertificate | String | None | A base64 representation of the whole certificate file, must include the private key |
ViewOnly | Switch | False | If present, remote viewer is only allowed to view the desktop (Mouse and Keyboard are not authorized) |
Server Address Examples
Value | Description |
---|---|
127.0.0.1 | Only listen for localhost connection (most likely for debugging purpose) |
0.0.0.0 | Listen on all network interfaces (Local, LAN, WAN) |
Clipboard Mode Enum Properties
Value | Description |
---|---|
Disabled | Clipboard synchronization is disabled in both side |
Receive | Only incomming clipboard is allowed |
Send | Only outgoing clipboard is allowed |
Both | Clipboard synchronization is allowed on both side |
⚠️ Important Notices
- Prefer using
SecurePassword
over plain-text password even if a plain-text password is getting converted toSecureString
anyway. - Not specifying a custom certificate using
CertificateFile
orEncodedCertificate
result in generating a default self-signed certificate (if not already generated) that will get installed on local machine thus requiring administrator privilege. If you want to run the server as a non-privileged account, specify your own certificate location. - If you don't specify a
SecurePassword
orPassword
, a random complex password will be generated and displayed on terminal (this password is temporary).
Examples
Invoke-RemoteDesktopServer -ListenAddress "0.0.0.0" -ListenPort 2801 -SecurePassword (ConvertTo-SecureString -String "[email protected]" -AsPlainText -Force) Invoke-RemoteDesktopServer -ListenAddress "0.0.0.0" -ListenPort 2801 -SecurePassword (ConvertTo-SecureString -String "[email protected]" -AsPlainText -Force) -CertificateFile "c:\certs\phrozen.p12"
Generate and pass your own X509 Certificate
Fortunately, you can easily create your own X509 certificate for example with the help of 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)
- Desktop images are now transported in raw bytes instead of base64 string thus slightly improving performances.
- Protocol has drastically changed. It is smoother to read and less prone to errors.
- TLS v1.3 option added (Might not be supported by some systems).
- Several code optimization, refactoring and fixes.
- Password complexity check implemented to avoid lazy passwords.
- Possibility to disable verbose.
- Server & Viewer version synchronization. Same version must be used between the two.
12 January 2022 (1.0.2 Beta 3)
- HDPI is completely supported.
12 January 2022 (1.0.3 Beta 4)
- Possibility to change desktop image quality.
- Possibility to choose which screen to capture if multiple screens (Monitors) are present on remote machine.
Multi Screen Selection
14 January 2022 (1.0.4 Beta 5)
- Password is stored as SecureString on Viewer. I don't see the point of implementing SecureString sever-side, if you do see the point, please change my mind.
- Server Fingerprint Validation.
- Possibility to trust a server for current PowerShell Instance or persistantly using a local storage.
- Possibility to manage trusted servers (List, Remove, Remove All)
Fingerprint Validation
18 January 2022 (1.0.5 Beta 6)
- Multiple code improvements to support incoming / outgoing events.
- Global cursor state synchronization implemented (Now virtual desktop mouse cursor is the same as remote server).
- Password Generator algorithm fixed.
- Virtual keyboard
]
and)
correctly sent and interpreted. - Clipboard synchronization Viewer <-> Server added.
- Server support a new option to only show desktop (Mouse moves, clicks, wheel and keyboard control is disabled in this mode).
21 January 2022 (1.0.6)
- TransportMode option removed.
- Desktop streaming performance / speed increased.
28 January 2022 (2.0.0)
- Protocol was completely revisited, protocol is now more stable and modular.
- Session concurrency is now supported, multiple viewers can connect at the same time to a server.
- Possibility to stop the server using CTRL+C
- Image quality is now requested by viewer.
- Desktop resize is now made server-side.
- Desktop resize can now be forced and requested by viewer.
- Center virtual desktop glitch fixed.
- Handshake calls (auth + session / worker negociation) will now timeout to avoid possible dead locks.
- Virtual Desktop Form can now be set always on top of other forms.
- Server finally use secure string to handle password-authentication.
multi-screen-demo.mp4
List of ideas and TODO
🟢 Support Password Protected external Certificates.🟢 Mutual Authentication for SSL/TLS (Client Certificate).🟠 Listen for local/remote screen resolution update event.🔴 Motion Update for Desktop Streaming (Only send and update changing parts of desktop).
We are doing our best to prepare the content of this app. However, PHROZEN SASU and / or Jean-Pierre LESUEUR cannot warranty the expressions and suggestions of the contents, as well as its accuracy. In addition, to the extent permitted by the law, PHROZEN SASU and / or Jean-Pierre LESUEUR shall not be responsible for any losses and/or damages due to the usage of the information on our app.
By using our app, you hereby consent to our disclaimer and agree to its terms.
Any links contained in our app may lead to external sites are provided for convenience only. Any information or statements that appeared in these sites or app are not sponsored, endorsed, or otherwise approved by PHROZEN SASU and / or Jean-Pierre LESUEUR. For these external sites, PHROZEN SASU and / or Jean-Pierre LESUEUR cannot be held liable for the availability of, or the content located on or through it. Plus, any losses or damages occurred from using these contents or the internet generally.
Made with