# Hawthorn Remote Support Setup # Run: irm https://hawthornconsulting.net/setup.ps1 | iex # Installs RustDesk (pre-configured) + Tailscale (SSH access) + Enables OpenSSH $ErrorActionPreference = "Stop" # --- Configuration --- $RustDeskServer = "vpn.gorackup.com" $RustDeskKey = "d3Qo6vL4ZMAnQewtDNXPMEugV2F9sQ5+WQNtARMHYeA=" $TailscaleAuthKey = "$env:TS_AUTHKEY" # Passed as env var or prompted $TempDir = "$env:TEMP\hawthorn-setup" Write-Host "" Write-Host "========================================" -ForegroundColor Cyan Write-Host " Hawthorn Remote Support Setup" -ForegroundColor Cyan Write-Host "========================================" -ForegroundColor Cyan Write-Host "" # Check admin $isAdmin = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) if (-not $isAdmin) { Write-Host "[!] This script requires Administrator privileges." -ForegroundColor Red Write-Host " Right-click PowerShell and select 'Run as Administrator'" -ForegroundColor Yellow Write-Host "" Read-Host "Press Enter to exit" exit 1 } # Create temp directory New-Item -ItemType Directory -Force -Path $TempDir | Out-Null # ============================================ # STEP 1: Install RustDesk # ============================================ Write-Host "[1/5] Installing RustDesk..." -ForegroundColor Green $rustdeskInstalled = Test-Path "C:\Program Files\RustDesk\rustdesk.exe" if ($rustdeskInstalled) { Write-Host " RustDesk already installed, skipping download." -ForegroundColor Yellow } else { # Get latest version from GitHub Write-Host " Checking for latest RustDesk version..." [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 $releaseInfo = (Invoke-RestMethod -Uri "https://api.github.com/repos/rustdesk/rustdesk/releases/latest" -UseBasicParsing) $RustDeskVersion = $releaseInfo.tag_name Write-Host " Latest version: $RustDeskVersion" $rustdeskUrl = "https://github.com/rustdesk/rustdesk/releases/download/$RustDeskVersion/rustdesk-$RustDeskVersion-x86_64.exe" $rustdeskInstaller = "$TempDir\rustdesk-setup.exe" Write-Host " Downloading RustDesk $RustDeskVersion..." [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 Invoke-WebRequest -Uri $rustdeskUrl -OutFile $rustdeskInstaller -UseBasicParsing Write-Host " Installing (silent)..." Start-Process -FilePath $rustdeskInstaller -ArgumentList "--silent-install" -Wait -NoNewWindow Start-Sleep -Seconds 3 } # ============================================ # STEP 2: Configure RustDesk with our server # ============================================ Write-Host "[2/5] Configuring RustDesk..." -ForegroundColor Green $configDir = "$env:APPDATA\RustDesk\config" New-Item -ItemType Directory -Force -Path $configDir | Out-Null # Write RustDesk2.toml with our server config $rustdeskConfig = @" rendezvous_server = '$RustDeskServer' nat_type = 1 serial = 0 [options] custom-rendezvous-server = '$RustDeskServer' key = '$RustDeskKey' "@ Set-Content -Path "$configDir\RustDesk2.toml" -Value $rustdeskConfig -Force Write-Host " Server configured: $RustDeskServer" # Restart RustDesk to pick up config Stop-Process -Name "rustdesk" -Force -ErrorAction SilentlyContinue Start-Sleep -Seconds 2 if (Test-Path "C:\Program Files\RustDesk\rustdesk.exe") { Start-Process "C:\Program Files\RustDesk\rustdesk.exe" -WindowStyle Minimized } Start-Sleep -Seconds 3 # Get RustDesk ID $rustdeskId = "" try { $idFile = "$configDir\RustDesk.toml" if (Test-Path $idFile) { $content = Get-Content $idFile -Raw if ($content -match 'id\s*=\s*''(\d+)''') { $rustdeskId = $Matches[1] } } # Fallback: try CLI if (-not $rustdeskId -and (Test-Path "C:\Program Files\RustDesk\rustdesk.exe")) { $rustdeskId = & "C:\Program Files\RustDesk\rustdesk.exe" --get-id 2>$null } } catch {} # ============================================ # STEP 3: Enable OpenSSH Server # ============================================ Write-Host "[3/5] Enabling OpenSSH Server..." -ForegroundColor Green # Install OpenSSH Server if not present $sshCapability = Get-WindowsCapability -Online | Where-Object Name -like 'OpenSSH.Server*' if ($sshCapability.State -ne 'Installed') { Write-Host " Installing OpenSSH Server..." Add-WindowsCapability -Online -Name 'OpenSSH.Server~~~~0.0.1.0' | Out-Null Write-Host " OpenSSH Server installed." -ForegroundColor Green } else { Write-Host " OpenSSH Server already installed." -ForegroundColor Yellow } # Start and enable the service Set-Service -Name sshd -StartupType Automatic Start-Service sshd -ErrorAction SilentlyContinue Write-Host " SSH service started and set to auto-start." # Firewall rule for SSH (port 22) $fwRule = Get-NetFirewallRule -Name 'OpenSSH-Server-In-TCP' -ErrorAction SilentlyContinue if (-not $fwRule) { New-NetFirewallRule -Name 'OpenSSH-Server-In-TCP' -DisplayName 'OpenSSH Server (sshd)' ` -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22 | Out-Null Write-Host " Firewall rule created for SSH (port 22)." } else { # Make sure it's enabled Set-NetFirewallRule -Name 'OpenSSH-Server-In-TCP' -Enabled True Write-Host " Firewall rule for SSH already exists (ensured enabled)." -ForegroundColor Yellow } # Set default shell to PowerShell for SSH sessions $regPath = "HKLM:\SOFTWARE\OpenSSH" if (-not (Test-Path $regPath)) { New-Item -Path $regPath -Force | Out-Null } New-ItemProperty -Path $regPath -Name DefaultShell -Value "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -PropertyType String -Force | Out-Null Write-Host " Default SSH shell set to PowerShell." # ============================================ # STEP 4: Install Tailscale # ============================================ Write-Host "[4/5] Installing Tailscale..." -ForegroundColor Green $tailscaleInstalled = Test-Path "C:\Program Files\Tailscale\tailscale.exe" if ($tailscaleInstalled) { Write-Host " Tailscale already installed, skipping download." -ForegroundColor Yellow } else { $tailscaleUrl = "https://pkgs.tailscale.com/stable/tailscale-setup-latest.exe" $tailscaleInstaller = "$TempDir\tailscale-setup.exe" Write-Host " Downloading Tailscale..." Invoke-WebRequest -Uri $tailscaleUrl -OutFile $tailscaleInstaller -UseBasicParsing Write-Host " Installing (silent)..." Start-Process -FilePath $tailscaleInstaller -ArgumentList "/S" -Wait -NoNewWindow Start-Sleep -Seconds 5 } # ============================================ # STEP 5: Connect Tailscale with SSH # ============================================ Write-Host "[5/5] Connecting Tailscale..." -ForegroundColor Green $tailscaleExe = "C:\Program Files\Tailscale\tailscale.exe" if (Test-Path $tailscaleExe) { if ($TailscaleAuthKey) { Write-Host " Joining Hawthorn network with SSH enabled..." & $tailscaleExe up --authkey=$TailscaleAuthKey --ssh 2>$null Start-Sleep -Seconds 3 $tsIp = & $tailscaleExe ip -4 2>$null Write-Host " Connected! Tailscale IP: $tsIp" -ForegroundColor Green } else { Write-Host " No auth key provided. Tailscale installed but not connected." -ForegroundColor Yellow Write-Host " Hawthorn will send you a connection link separately." -ForegroundColor Yellow } } else { Write-Host " Tailscale not found after install." -ForegroundColor Red } # ============================================ # DONE - Show summary # ============================================ Write-Host "" Write-Host "========================================" -ForegroundColor Green Write-Host " Setup Complete!" -ForegroundColor Green Write-Host "========================================" -ForegroundColor Green Write-Host "" if ($rustdeskId) { Write-Host " Your RustDesk ID: $rustdeskId" -ForegroundColor Cyan Write-Host "" Write-Host " Please send this ID to Hawthorn Consulting" -ForegroundColor White Write-Host " Email: support@hawthornconsulting.net" -ForegroundColor White Write-Host " Phone: (918) 922-0417" -ForegroundColor White } else { Write-Host " RustDesk is installed. Open it to find your ID." -ForegroundColor Yellow Write-Host " Send your ID to Hawthorn Consulting." -ForegroundColor White } Write-Host "" Write-Host " What was set up:" -ForegroundColor White Write-Host " [x] RustDesk (remote desktop support)" -ForegroundColor Gray Write-Host " [x] OpenSSH Server (enabled + firewall opened)" -ForegroundColor Gray Write-Host " [x] Tailscale (secure network access)" -ForegroundColor Gray Write-Host "" # Cleanup Remove-Item -Path $TempDir -Recurse -Force -ErrorAction SilentlyContinue Read-Host "Press Enter to close"