Last active
June 24, 2026 18:08
-
-
Save lalibi/c4707d4f62f174d24df4cf12348aaa65 to your computer and use it in GitHub Desktop.
Install-RustDesk.ps1
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Usage: | |
| # 1) Run this command in PowerShell, as Administrator: | |
| # irm https://gist.githubusercontent.com/lalibi/c4707d4f62f174d24df4cf12348aaa65/raw/Install-RustDesk.ps1 | iex | |
| # or | |
| # 2) Download the script and run it: | |
| # irm https://gist.githubusercontent.com/lalibi/c4707d4f62f174d24df4cf12348aaa65/raw/Install-RustDesk.ps1 -out Install-Rustdesk.ps1; iex .\Install-Rustdesk.ps1 | |
| # References: | |
| # Client Deployment :: Documentation for RustDesk - https://tinyurl.com/258x3hhd | |
| $ErrorActionPreference = 'Stop' | |
| function Exit-WithMessage($Message, [switch] $IsError) { | |
| Write-Host | |
| Write-Host $Message -ForegroundColor $(if ($IsError) { 'Red' } else { 'Green' }) | |
| Write-Host | |
| Read-Host "Press Enter to continue..." | |
| exit $(if ($IsError) { 1 } else { 0 }) | |
| } | |
| # Ensure script is running as administrator | |
| if (-not ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) { | |
| Write-Host | |
| Write-Host "Restarting script as Administrator..." -ForegroundColor Cyan | |
| Write-Host | |
| Start-Process PowerShell -Verb RunAs -ArgumentList "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`"" | |
| exit | |
| } | |
| # Check if RustDesk is installed | |
| $installed = $false | |
| $installed_version = $null | |
| try { | |
| $rd_key = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\RustDesk" | |
| if (Test-Path $rd_key) { | |
| $installed_version = (Get-ItemProperty $rd_key).Version | |
| $installed = $true | |
| } | |
| } | |
| catch {} | |
| $update_only = $false | |
| $rustdesk_custom_id = $null | |
| if ($installed) { | |
| Write-Host | |
| Write-Host "RustDesk version $installed_version is already installed." -ForegroundColor Yellow | |
| Write-Host | |
| do { | |
| $choice = Read-Host "Do you want to (U)pdate only or (R)e-install with new server config? [U/R]" | |
| if ($choice -match '^[Uu]') { | |
| $update_only = $true | |
| break | |
| } | |
| elseif ($choice -match '^[Rr]') { | |
| $update_only = $false | |
| break | |
| } | |
| else { | |
| Write-Host "Invalid choice. Please enter <U> or <R>." -ForegroundColor Red | |
| Write-Host | |
| } | |
| } while ($true) | |
| } | |
| # Only prompt for input if it's not update-only | |
| if (-not $update_only) { | |
| Write-Host | |
| $server_ip = Read-Host -Prompt 'Enter the server IP (<Enter> for none)' | |
| $server_key = Read-Host -Prompt 'Enter the server public key (<Enter> for none)' | |
| $rustdesk_custom_id = Read-Host -Prompt 'Enter a custom RustDesk ID (<Enter> for generated/default)' | |
| $rustdesk_pw = Read-Host -Prompt 'Enter a permanent password (<Enter> for random)' | |
| if (-not [string]::IsNullOrWhiteSpace($rustdesk_custom_id)) { | |
| $rustdesk_custom_id = $rustdesk_custom_id.Trim() | |
| if ($rustdesk_custom_id -notmatch '^[A-Za-z][A-Za-z0-9_]{5,15}$') { | |
| Exit-WithMessage "Invalid custom ID. Use 6-16 chars, start with a letter, and only use letters, numbers, or underscore." -IsError | |
| } | |
| } | |
| if ([string]::IsNullOrWhiteSpace($rustdesk_pw)) { | |
| $rustdesk_pw = -join ((65..90) + (97..122) + (48..57) | Get-Random -Count 16 | ForEach-Object { [char]$_ }) | |
| } | |
| Write-Host | |
| } | |
| # Add a blank line before checking version | |
| Write-Host | |
| Write-Host "Checking latest version of RustDesk..." -ForegroundColor Cyan | |
| # Get the latest release information from GitHub API | |
| try { | |
| $uri = "https://api.github.com/repos/rustdesk/rustdesk/releases/latest" | |
| $release = Invoke-WebRequest -Uri $uri -UseBasicParsing | ConvertFrom-Json | |
| } | |
| catch { | |
| Exit-WithMessage "Error retrieving latest release information: $_" -IsError | |
| } | |
| $latest_version = $release.tag_name | |
| $installer_asset = $release.assets | Where-Object { $_.name -like "*x86_64.exe" } | Select-Object -First 1 | |
| if (-not $installer_asset) { | |
| Exit-WithMessage "Unable to locate the installer asset for x86_64." -IsError | |
| } | |
| $installer_name = $installer_asset.name | |
| $installer_url = $installer_asset.browser_download_url | |
| <# if ($installed -and $installed_version -eq $latest_version) { | |
| Exit-WithMessage "RustDesk is already at the latest version ($installed_version). No update needed." | |
| } #> | |
| Write-Host | |
| Write-Host "Downloading RustDesk $latest_version..." -ForegroundColor Cyan | |
| Push-Location $env:TEMP | |
| # Remove any existing installer file to avoid conflicts | |
| if (Test-Path $installer_name) { | |
| Remove-Item -Path $installer_name -Force -ErrorAction SilentlyContinue | |
| } | |
| try { | |
| Invoke-WebRequest -Uri $installer_url -OutFile $installer_name -ErrorAction Stop | |
| } | |
| catch { | |
| Pop-Location | |
| Exit-WithMessage "Error downloading installer: $_" -IsError | |
| } | |
| $process_name = $service_name = "Rustdesk" | |
| try { | |
| $processes = Get-Process -Name $process_name -ErrorAction SilentlyContinue | |
| if ($processes) { | |
| Write-Host | |
| Write-Host "Stopping existing RustDesk processes..." -ForegroundColor Yellow | |
| Stop-Process -Name "rustdesk" -Force -ErrorAction SilentlyContinue | |
| } | |
| Write-Host | |
| Write-Host "Installing RustDesk..." -ForegroundColor Cyan | |
| Start-Process -FilePath ".\$installer_name" -ArgumentList "--silent-install" -ErrorAction Stop | |
| do { | |
| Start-Sleep -Seconds 2 | |
| $service = Get-Service -Name $service_name -ErrorAction SilentlyContinue | |
| } while ($service -eq $null) | |
| } | |
| catch { | |
| Pop-Location | |
| Exit-WithMessage "Installation failed: $_" -IsError | |
| } | |
| if (Test-Path $installer_name) { | |
| Remove-Item -Path $installer_name -Force -ErrorAction SilentlyContinue | |
| } | |
| Write-Host | |
| Write-Host "Installation completed." -ForegroundColor Green | |
| Pop-Location | |
| # Wait for installation to complete, with timeout after 60 seconds | |
| $timeout = 60 | |
| $elapsed = 0 | |
| while (-not (Test-Path "$env:ProgramFiles\RustDesk") -and ($elapsed -lt $timeout)) { | |
| Start-Sleep -Seconds 2 | |
| $elapsed += 2 | |
| } | |
| if ($elapsed -ge $timeout) { | |
| Exit-WithMessage "RustDesk did not install within the expected time ($timeout seconds)." -IsError | |
| } | |
| # Apply server configuration if not update-only and if a server IP was provided | |
| if (-not $update_only -and $server_ip) { | |
| try { | |
| Stop-Service -Name $service_name -ErrorAction Stop | |
| } | |
| catch { | |
| Write-Host "Warning: Could not stop RustDesk service: $_" -ForegroundColor Yellow | |
| } | |
| $config_file_name = 'RustDesk2.toml' | |
| $user_config_path = Join-Path $env:APPDATA "RustDesk\config\$config_file_name" | |
| $service_config_path = Join-Path $env:WINDIR "ServiceProfiles\LocalService\AppData\Roaming\RustDesk\config\$config_file_name" | |
| $config_content = @" | |
| rendezvous_server = '$server_ip' | |
| nat_type = 1 | |
| serial = 0 | |
| [options] | |
| custom-rendezvous-server = '$server_ip' | |
| relay-server = '$server_ip' | |
| api-server = '' | |
| key = '$server_key' | |
| "@ | |
| foreach ($path in @($user_config_path, $service_config_path)) { | |
| $dir = Split-Path $path | |
| if (-not (Test-Path $dir)) { | |
| New-Item -ItemType Directory -Path $dir -Force | Out-Null | |
| } | |
| Set-Content -Path $path -Value $config_content -Force | |
| } | |
| } | |
| Push-Location "$env:ProgramFiles\RustDesk" | |
| $service = Get-Service -Name $service_name -ErrorAction SilentlyContinue | |
| if ($null -eq $service) { | |
| Write-Host | |
| Write-Host "RustDesk service not found. Installing service..." -ForegroundColor Yellow | |
| Start-Process .\rustdesk.exe --install-service | |
| # Wait for the service to be created | |
| do { | |
| Start-Sleep -Seconds 2 | |
| $service = Get-Service -Name $service_name -ErrorAction SilentlyContinue | |
| } while ($service -eq $null) | |
| } | |
| while ($service.Status -ne 'Running') { | |
| Start-Service $service_name | |
| Start-Sleep -Seconds 2 | |
| $service = Get-Service -Name $service_name -ErrorAction SilentlyContinue | |
| $service.Refresh() | |
| } | |
| if (-not $update_only) { | |
| if (-not [string]::IsNullOrWhiteSpace($rustdesk_custom_id)) { | |
| try { | |
| Write-Host | |
| Write-Host "Setting custom RustDesk ID: $rustdesk_custom_id" -ForegroundColor Cyan | |
| .\rustdesk.exe --set-id $rustdesk_custom_id | |
| Start-Sleep -Seconds 2 | |
| try { | |
| Stop-Process -Name "rustdesk" -Force -ErrorAction SilentlyContinue | |
| Restart-Service -Name $service_name -Force -ErrorAction SilentlyContinue | |
| Start-Sleep -Seconds 3 | |
| } | |
| catch { | |
| Write-Host "Warning: Could not restart RustDesk after setting custom ID: $_" -ForegroundColor Yellow | |
| } | |
| } | |
| catch { | |
| Write-Host "Error setting custom RustDesk ID: $_" -ForegroundColor Red | |
| } | |
| } | |
| try { | |
| .\rustdesk.exe --password $rustdesk_pw | |
| } | |
| catch { | |
| Write-Host "Error setting RustDesk password: $_" -ForegroundColor Red | |
| } | |
| try { | |
| Start-Sleep -Seconds 2 | |
| $rustdesk_id = .\rustdesk.exe --get-id | |
| } | |
| catch { | |
| Pop-Location | |
| Exit-WithMessage "Error retrieving RustDesk ID: $_" -IsError | |
| } | |
| Write-Host | |
| Write-Host ('-' * 50) -ForegroundColor Gray | |
| Write-Host "RustDesk ID: $rustdesk_id" -ForegroundColor Green | |
| Write-Host "RustDesk Password: $rustdesk_pw" -ForegroundColor Green | |
| if (-not [string]::IsNullOrWhiteSpace($rustdesk_custom_id) -and $rustdesk_id -ne $rustdesk_custom_id) { | |
| Write-Host "Warning: Requested custom ID was '$rustdesk_custom_id', but RustDesk reports '$rustdesk_id'." -ForegroundColor Yellow | |
| Write-Host "The ID may already be taken, rejected by the server, or unsupported by this RustDesk version." -ForegroundColor Yellow | |
| } | |
| Write-Host ('-' * 50) -ForegroundColor Gray | |
| } | |
| Pop-Location | |
| Write-Host | |
| Write-Host "All done! RustDesk is installed and ready." -ForegroundColor Cyan | |
| Write-Host | |
| Read-Host "Press <Enter> to continue..." |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment