# 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 = 'https://support.freakma.com' $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"