# install.ps1 — Windows installer for the restic-manager agent (P2-17). # # Usage (Run as administrator): # $env:RM_SERVER = "https://restic.lab.example" # $env:RM_TOKEN = "" # omit for announce-and-approve # iwr "$env:RM_SERVER/install/install.ps1" -UseBasicParsing | iex # # What it does: # 1. checks for admin elevation # 2. downloads the matching agent binary from the server # 3. lays down C:\Program Files\restic-manager\ and # C:\ProgramData\restic-manager\ (config + state) # 4. registers the agent as a Windows service via the agent's own # `install` subcommand (which uses the SCM API) # 5. enrolls (token flow if RM_TOKEN set, otherwise announce flow) # by spawning the agent with the right CLI flags and waits # until config is written # 6. surfaces (but does NOT disable) any existing scheduled tasks # whose name contains "restic" so the operator can decide # # Idempotent — safe to re-run. [CmdletBinding()] param( [string]$Server = $env:RM_SERVER, [string]$Token = $env:RM_TOKEN, [string]$InstallDir = 'C:\Program Files\restic-manager', [string]$DataDir = 'C:\ProgramData\restic-manager' ) $ErrorActionPreference = 'Stop' function Test-Admin { $id = [System.Security.Principal.WindowsIdentity]::GetCurrent() $pri = New-Object System.Security.Principal.WindowsPrincipal($id) return $pri.IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator) } function Detect-Arch { switch ($env:PROCESSOR_ARCHITECTURE) { 'AMD64' { return 'amd64' } 'ARM64' { return 'arm64' } default { throw "unsupported PROCESSOR_ARCHITECTURE: $($env:PROCESSOR_ARCHITECTURE)" } } } function Detect-ResticTasks { Write-Host '' Write-Host '— Existing restic-named scheduled tasks (review manually) —' try { $tasks = Get-ScheduledTask -ErrorAction SilentlyContinue | Where-Object { $_.TaskName -match 'restic' -or $_.TaskPath -match 'restic' } if ($tasks) { foreach ($t in $tasks) { Write-Host " * $($t.TaskPath)$($t.TaskName) state=$($t.State)" Write-Host " Disable with: Disable-ScheduledTask -TaskName '$($t.TaskName)' -TaskPath '$($t.TaskPath)'" } } else { Write-Host ' (none found)' } } catch { Write-Host ' (Get-ScheduledTask failed; review the Task Scheduler UI manually)' } Write-Host '' } # --- preflight ------------------------------------------------------- if (-not (Test-Admin)) { throw 'install.ps1: must be run from an elevated PowerShell (Run as administrator).' } if (-not $Server) { throw 'install.ps1: -Server (or $env:RM_SERVER) is required, e.g. https://restic.lab.example' } $arch = Detect-Arch Write-Host "install.ps1: server=$Server arch=$arch" # --- directories ----------------------------------------------------- New-Item -ItemType Directory -Force -Path $InstallDir | Out-Null New-Item -ItemType Directory -Force -Path $DataDir | Out-Null # --- download agent -------------------------------------------------- $agentExe = Join-Path $InstallDir 'restic-manager-agent.exe' $tmpExe = "$agentExe.tmp" $dlURL = "$Server/agent/binary?os=windows&arch=$arch" Write-Host "install.ps1: downloading $dlURL" Invoke-WebRequest -UseBasicParsing -Uri $dlURL -OutFile $tmpExe # Atomic-ish replace: stop service if running so the .exe isn't busy. try { Stop-Service -Name 'restic-manager-agent' -ErrorAction SilentlyContinue } catch {} Move-Item -Force -Path $tmpExe -Destination $agentExe # --- enroll / announce ----------------------------------------------- $cfgPath = Join-Path $DataDir 'agent.yaml' $args = @('-config', $cfgPath, '-enroll-server', $Server) if ($Token) { $args += @('-enroll-token', $Token) Write-Host 'install.ps1: enrolling with one-time token' } else { Write-Host 'install.ps1: no RM_TOKEN — running announce-and-approve flow.' Write-Host ' The fingerprint will print below. Compare it with the dashboard before clicking Accept.' } & $agentExe @args if ($LASTEXITCODE -ne 0) { throw "install.ps1: agent enrolment failed (exit $LASTEXITCODE)" } # --- install + start service ---------------------------------------- # The 'install' subcommand registers the service via the SCM. If # already registered, it errors loudly — re-run with -Force only if # you've manually verified. try { & $agentExe install } catch { Write-Host "install.ps1: service may already be registered ($_); continuing." } try { Start-Service -Name 'restic-manager-agent' } catch { Write-Host "install.ps1: Start-Service failed ($_); check Event Viewer." } Detect-ResticTasks Write-Host '' Write-Host 'install.ps1: done.' Write-Host " config : $cfgPath" Write-Host " binary : $agentExe" Write-Host " service: restic-manager-agent (Get-Service to inspect)"