diff --git a/template/Setup-WinBuild2025.ps1 b/template/Setup-WinBuild2025.ps1 index ab3dd76..40c89ed 100644 --- a/template/Setup-WinBuild2025.ps1 +++ b/template/Setup-WinBuild2025.ps1 @@ -1199,8 +1199,21 @@ if (Test-Path $nsisExe) { $nsisUrl = "https://prdownloads.sourceforge.net/nsis/nsis-$NSISVersion-setup.exe" $nsisInstaller = 'C:\CI\nsis_installer.exe' Write-Host "Downloading NSIS $NSISVersion from SourceForge..." - try { Invoke-WebRequest -Uri $nsisUrl -OutFile $nsisInstaller -UseBasicParsing } - catch { throw "Failed to download NSIS from '$nsisUrl': $_" } + # SourceForge returns an HTML redirect page when accessed with PS default User-Agent. + # Supplying a browser-like User-Agent forces the CDN to serve the raw binary. + try { + Invoke-WebRequest -Uri $nsisUrl -OutFile $nsisInstaller -UseBasicParsing ` + -Headers @{ 'User-Agent' = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)' } + } catch { throw "Failed to download NSIS from '$nsisUrl': $_" } + # Guard: verify downloaded file is a valid PE executable (MZ magic bytes). + # If SourceForge still returned an HTML page the installer would silently corrupt + # the WinRM session — fail fast with a clear message instead. + $peBytes = [System.IO.File]::ReadAllBytes($nsisInstaller) + if ($peBytes.Length -lt 2 -or $peBytes[0] -ne 0x4D -or $peBytes[1] -ne 0x5A) { + Remove-Item $nsisInstaller -ErrorAction SilentlyContinue + throw "NSIS download is not a valid PE executable (MZ header missing). " + + "SourceForge likely returned an HTML page. Set `$script:Hashes['NSIS']` to pin a known-good hash." + } Assert-Hash -FilePath $nsisInstaller -Label "nsis-$NSISVersion-setup.exe" ` -Expected $script:Hashes['NSIS'] Write-Host "Installing NSIS $NSISVersion (silent /S)..."