feat(install): one-command device registration for macOS, Windows and Linux
Registering a machine meant reading a multi-step page, installing Node, and running three commands in the right order. Now it is one line per platform. The hub serves scripts/install.sh and scripts/install.ps1 with its own address and the enrolment token substituted in, so the published command carries everything and there is nothing to fill in: curl -fsSL https://support.freakma.com/install.sh?token=TOKEN | sh irm https://support.freakma.com/install.ps1?token=TOKEN | iex That output is piped straight into a shell, so the token — the only untrusted value in either file — is refused unless it matches the base64url shape that randomToken produces. Each script checks for a usable runtime and stops with instructions rather than guessing, warns when nothing is serving RFB on the loopback, installs per-user with no root or administrator, and registers a login-scoped service: launchd on macOS, a lingering systemd user service on Linux, a logon task on Windows. The Windows script uses Node 22 when it is present and falls back to the bundled executable otherwise, which is what lets one command cover both Windows 11 and Server 2008 R2. It registers a logon task rather than a service on purpose: services run in session 0 and cannot draw on the interactive desktop, so the "ask first" consent prompt would never appear. Also adds /docs — a per-OS setup guide with service management and a troubleshooting table — and reworks the enrolment page into OS tabs that open on whichever platform the reader is sitting at. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,106 @@
|
||||
# Remote Control Support - agent installer for Windows.
|
||||
#
|
||||
# Served from the hub, which substitutes HUB and TOKEN below before sending it:
|
||||
#
|
||||
# irm https://support.freakma.com/install.ps1?token=TOKEN | iex
|
||||
#
|
||||
# Windows 7 / Server 2008 R2 ship PowerShell 2.0, which has no Invoke-RestMethod
|
||||
# and no TLS 1.2, so those machines need the longer form instead:
|
||||
#
|
||||
# powershell -c "[Net.ServicePointManager]::SecurityProtocol=3072; (New-Object Net.WebClient).DownloadString('https://support.freakma.com/install.ps1?token=TOKEN') | iex"
|
||||
#
|
||||
# Everything is written under %LOCALAPPDATA%. No administrator rights needed.
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
$Hub = '__HUB__'
|
||||
$Token = '__TOKEN__'
|
||||
|
||||
# .NET 3.5 has no Tls12 enum member, so the numeric value is the portable way.
|
||||
# Harmless on modern Windows, essential on 2008 R2 (which also needs KB3154518).
|
||||
try { [Net.ServicePointManager]::SecurityProtocol = 3072 } catch { }
|
||||
|
||||
function Write-Step { param($m) Write-Host "> $m" -ForegroundColor Cyan }
|
||||
function Write-Warn { param($m) Write-Host "! $m" -ForegroundColor Yellow }
|
||||
function Write-Die { param($m) Write-Host "x $m" -ForegroundColor Red; exit 1 }
|
||||
|
||||
if (-not $Token) {
|
||||
Write-Die "no enrolment token. Open the invite link on this machine to get the full command."
|
||||
}
|
||||
|
||||
$InstallDir = Join-Path $env:LOCALAPPDATA 'RemoteControlSupport'
|
||||
$Config = Join-Path $InstallDir 'config.json'
|
||||
$TaskName = 'RemoteControlSupportAgent'
|
||||
|
||||
if (-not (Test-Path $InstallDir)) { New-Item -ItemType Directory -Path $InstallDir | Out-Null }
|
||||
|
||||
$client = New-Object Net.WebClient
|
||||
|
||||
# ------------------------------------------------------------------ runtime
|
||||
|
||||
# Node 22 is preferred where it exists: smaller download, current runtime. Where
|
||||
# it does not - which includes every Windows 7 and Server 2008 R2 box, since
|
||||
# Node 14 dropped them - the self-contained executable carries its own Node 12.
|
||||
$NodeMajor = 0
|
||||
try { $NodeMajor = [int]((& node -p 'process.versions.node.split(".")[0]') 2>$null) } catch { }
|
||||
|
||||
if ($NodeMajor -ge 22) {
|
||||
Write-Step "using the Node.js $NodeMajor already installed here"
|
||||
$AgentPath = Join-Path $InstallDir 'agent.js'
|
||||
$client.DownloadFile("$Hub/download/agent.js", $AgentPath)
|
||||
$Exe = 'node'
|
||||
$Args = @($AgentPath)
|
||||
} else {
|
||||
Write-Step "no Node.js 22+ here - downloading the self-contained agent (about 30 MB)"
|
||||
$AgentPath = Join-Path $InstallDir 'rcs-agent.exe'
|
||||
$client.DownloadFile("$Hub/download/agent.exe", $AgentPath)
|
||||
$Exe = $AgentPath
|
||||
$Args = @()
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------------- vnc
|
||||
|
||||
# Advisory: the agent enrols fine without it, but a session cannot start until
|
||||
# something is actually serving RFB on the loopback port.
|
||||
$vncUp = $false
|
||||
try {
|
||||
$probe = New-Object Net.Sockets.TcpClient
|
||||
$probe.Connect('127.0.0.1', 5900)
|
||||
$vncUp = $probe.Connected
|
||||
$probe.Close()
|
||||
} catch { }
|
||||
if (-not $vncUp) {
|
||||
Write-Warn "nothing is listening on 127.0.0.1:5900 - install TightVNC or UltraVNC and let it start on boot"
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------ enrol
|
||||
|
||||
Write-Step "enrolling with $Hub"
|
||||
& $Exe @($Args + @('enroll', "$Hub/enroll/$Token", '--config', $Config))
|
||||
if ($LASTEXITCODE -ne 0) { Write-Die "enrolment failed - the link may have expired" }
|
||||
|
||||
# --------------------------------------------------------------- scheduled
|
||||
|
||||
# A Windows *service* runs in session 0 and cannot draw on the interactive
|
||||
# desktop, so the "ask first" consent dialog would never appear. A logon task
|
||||
# runs in the console session, where it can. schtasks.exe is used rather than
|
||||
# Register-ScheduledTask because PowerShell 2.0 does not have that cmdlet.
|
||||
Write-Step "registering a logon task so it starts with Windows"
|
||||
|
||||
if ($Args.Count -gt 0) {
|
||||
$run = '"' + $Exe + '" "' + $Args[0] + '" run --config "' + $Config + '"'
|
||||
} else {
|
||||
$run = '"' + $Exe + '" run --config "' + $Config + '"'
|
||||
}
|
||||
|
||||
& schtasks.exe /create /tn $TaskName /tr $run /sc onlogon /f | Out-Null
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-Warn "could not register the logon task - start the agent by hand with: $run"
|
||||
} else {
|
||||
& schtasks.exe /run /tn $TaskName | Out-Null
|
||||
}
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "Done. This machine is registered and should now appear in the console."
|
||||
Write-Host "Installed in: $InstallDir"
|
||||
Write-Host "Remove with: schtasks /delete /tn $TaskName /f"
|
||||
Reference in New Issue
Block a user