<# .SYNOPSIS Build + sign a GuruRMM Agent MSI installer. .DESCRIPTION Downloads the signed agent binary for the target version, packages it into an MSI via WiX, signs the MSI with Azure Trusted Signing, and writes the result to the current directory. Requires: - .NET SDK 8 - wix global tool (dotnet tool install --global wix --version 5.0.2) - Azure Trusted Signing access via sign.ps1 at C:\tools\trusted-signing\ - az login session (DefaultAzureCredential) .EXAMPLE .\build-msi.ps1 -Version 0.6.1 .\build-msi.ps1 -Version 0.6.1 -SourceUrl https://rmm-api.azcomputerguru.com/downloads -SkipSign #> [CmdletBinding()] param( [Parameter(Mandatory)] [string] $Version, [string] $SourceUrl = 'https://rmm-api.azcomputerguru.com/downloads', [string] $WixExe = "$env:USERPROFILE\.dotnet\tools\wix.exe", [string] $SignScript = 'C:\tools\trusted-signing\sign.ps1', [switch] $SkipSign, [switch] $KeepSource ) $ErrorActionPreference = 'Stop' Set-Location $PSScriptRoot if (-not (Test-Path $WixExe)) { throw "wix.exe not found at $WixExe" } $srcDir = Join-Path $PSScriptRoot 'src' if (-not (Test-Path $srcDir)) { New-Item -ItemType Directory -Path $srcDir | Out-Null } $exePath = Join-Path $srcDir 'gururmm-agent.exe' $downloadUrl = "$SourceUrl/gururmm-agent-windows-amd64-$Version.exe" Write-Host "[1] Downloading signed agent $Version from $downloadUrl ..." -ForegroundColor Cyan Invoke-WebRequest -Uri $downloadUrl -OutFile $exePath -UseBasicParsing $sig = Get-AuthenticodeSignature $exePath if ($sig.Status -ne 'Valid') { throw "Downloaded agent has invalid or missing signature: $($sig.Status). Refusing to package an unsigned agent." } Write-Host " signed by: $($sig.SignerCertificate.Subject)" -ForegroundColor Gray $msiName = "gururmm-agent-$Version.msi" Write-Host "[2] Building $msiName via WiX ..." -ForegroundColor Cyan & $WixExe build gururmm.wxs -arch x64 -o $msiName -d "Version=$Version" if ($LASTEXITCODE -ne 0) { throw "wix build failed (exit $LASTEXITCODE)" } if (-not $SkipSign) { if (-not (Test-Path $SignScript)) { throw "sign.ps1 not found at $SignScript" } Write-Host "[3] Signing $msiName ..." -ForegroundColor Cyan & $SignScript -File (Join-Path $PSScriptRoot $msiName) ` -Description "GuruRMM Agent Installer v$Version" ` -Url 'https://www.azcomputerguru.com' ` -Verify if ($LASTEXITCODE -ne 0) { throw "signing failed (exit $LASTEXITCODE)" } } if (-not $KeepSource) { Remove-Item $exePath -ErrorAction SilentlyContinue } $msiPath = Join-Path $PSScriptRoot $msiName $hash = (Get-FileHash $msiPath -Algorithm SHA256).Hash.ToLower() $hash | Set-Content "$msiPath.sha256" "$hash $msiName" | Set-Content "$msiPath.sha256" Write-Host "" Write-Host "[DONE]" -ForegroundColor Green Write-Host " msi: $msiPath" Write-Host " sha256: $hash"