$ErrorActionPreference = "Stop" $BaseUrl = if ($env:CHORUS_BASE_URL) { $env:CHORUS_BASE_URL.TrimEnd("/") } else { "https://chorus.host" } $InstallDir = if ($env:CHORUS_INSTALL_DIR) { $env:CHORUS_INSTALL_DIR } else { Join-Path $env:LOCALAPPDATA "Programs\chorus" } $TempDir = New-Item -ItemType Directory -Path (Join-Path ([System.IO.Path]::GetTempPath()) ("chorus-" + [System.Guid]::NewGuid())) -Force try { $Arch = switch ((Get-CimInstance Win32_OperatingSystem).OSArchitecture) { { $_ -match "ARM64" } { "arm64"; break } default { "amd64" } } $LatestPath = Join-Path $TempDir "latest.json" Invoke-WebRequest "$BaseUrl/downloads/beacon/latest.json" -OutFile $LatestPath $Latest = Get-Content $LatestPath -Raw | ConvertFrom-Json $Version = $Latest.version if (-not $Version) { throw "Could not read version from latest.json" } $Name = "beacon-windows-$Arch.zip" $Archive = Join-Path $TempDir $Name Invoke-WebRequest "$BaseUrl/downloads/beacon/$Version/$Name" -OutFile $Archive Invoke-WebRequest "$BaseUrl/downloads/beacon/$Version/checksums.txt" -OutFile (Join-Path $TempDir "checksums.txt") $Expected = (Select-String -Path (Join-Path $TempDir "checksums.txt") -Pattern " $([Regex]::Escape($Name))$").Line.Split(" ")[0] $Actual = (Get-FileHash -Algorithm SHA256 $Archive).Hash.ToLowerInvariant() if ($Expected -and $Actual -ne $Expected.ToLowerInvariant()) { throw "Checksum mismatch for $Name" } Expand-Archive -Path $Archive -DestinationPath $TempDir -Force New-Item -ItemType Directory -Path $InstallDir -Force | Out-Null Copy-Item (Join-Path $TempDir "beacon.exe") (Join-Path $InstallDir "beacon.exe") -Force $UserPath = [Environment]::GetEnvironmentVariable("Path", "User") if ($UserPath -notlike "*$InstallDir*") { [Environment]::SetEnvironmentVariable("Path", "$UserPath;$InstallDir", "User") Write-Host "Added $InstallDir to your user PATH. Open a new terminal before running beacon." } Write-Host "Installed beacon $Version to $(Join-Path $InstallDir 'beacon.exe')" } finally { Remove-Item $TempDir -Recurse -Force -ErrorAction SilentlyContinue }