| 1 | $ErrorActionPreference = 'Stop' |
| 2 | $Server = __SERVER__ |
| 3 | |
| 4 | function Install-Agent { |
| 5 | $Identity = [Security.Principal.WindowsIdentity]::GetCurrent() |
| 6 | $Principal = New-Object Security.Principal.WindowsPrincipal($Identity) |
| 7 | if ($Principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) { |
| 8 | throw 'Run this installer from your usual PowerShell window, without administrator privileges.' |
| 9 | } |
| 10 | $Base = Join-Path $env:LOCALAPPDATA 'AgentRelay' |
| 11 | $Stage = Join-Path $Base ('.install.' + [guid]::NewGuid().ToString('N')) |
| 12 | New-Item -ItemType Directory -Force $Base | Out-Null |
| 13 | & icacls.exe $Base /inheritance:r /grant:r ('*' + $Identity.User.Value + ':(OI)(CI)F') '*S-1-5-18:(OI)(CI)F' | Out-Null |
| 14 | if ($LASTEXITCODE -ne 0) { throw 'Unable to protect the agent folder. Check its permissions and retry.' } |
| 15 | try { |
| 16 | New-Item -ItemType Directory -Force $Stage | Out-Null |
| 17 | $Node = Join-Path $Base 'node.exe' |
| 18 | if (!(Test-Path $Node)) { |
| 19 | Write-Host 'Downloading the agent runtime…' |
| 20 | $Arch = if ($env:PROCESSOR_ARCHITECTURE -eq 'ARM64' -or $env:PROCESSOR_ARCHITEW6432 -eq 'ARM64') { 'arm64' } else { 'x64' } |
| 21 | $Checksums = (Invoke-WebRequest -UseBasicParsing -TimeoutSec 30 'https://nodejs.org/dist/latest-v24.x/SHASUMS256.txt').Content |
| 22 | $Match = [regex]::Match($Checksums, "(?m)^([a-f0-9]{64})\s+(node-(v24\.[0-9]+\.[0-9]+)-win-$Arch\.zip)\s*$") |
| 23 | if (!$Match.Success) { throw 'No runtime download is available for this machine.' } |
| 24 | $Archive = Join-Path $Stage $Match.Groups[2].Value |
| 25 | Invoke-WebRequest -UseBasicParsing -TimeoutSec 120 ("https://nodejs.org/dist/" + $Match.Groups[3].Value + '/' + $Match.Groups[2].Value) -OutFile $Archive |
| 26 | if ((Get-FileHash $Archive -Algorithm SHA256).Hash.ToLowerInvariant() -ne $Match.Groups[1].Value) { |
| 27 | throw 'The runtime checksum did not match. Run the installer again.' |
| 28 | } |
| 29 | Expand-Archive $Archive $Stage |
| 30 | Copy-Item (Join-Path $Stage ($Match.Groups[2].Value.Replace('.zip', '') + '\node.exe')) $Node |
| 31 | } |
| 32 | Invoke-WebRequest -UseBasicParsing -TimeoutSec 30 "$Server/agent/relay.mjs" -OutFile (Join-Path $Stage 'relay.mjs') |
| 33 | Invoke-WebRequest -UseBasicParsing -TimeoutSec 30 "$Server/agent/setup.mjs" -OutFile (Join-Path $Stage 'setup.mjs') |
| 34 | & $Node (Join-Path $Stage 'setup.mjs') install $Server $Base |
| 35 | if ($LASTEXITCODE -ne 0) { throw 'Installation stopped. Correct the problem above, then run the installer again.' } |
| 36 | } finally { |
| 37 | Remove-Item -Recurse -Force $Stage |
| 38 | } |
| 39 | } |
| 40 | |
| 41 | Install-Agent |