<# .SYNOPSIS Nextxch v1.3.0 - Official One-Line Windows Installer & Auto-Updater (iqmeta GmbH) .DESCRIPTION Downloads the SHA-256-verified nextxch_1.3.0_setup-win-x64.msi from https://nextxch.com and launches either the interactive Windows Setup Wizard (prompting for Domain, Admin, SQLite / MS SQL Server / PostgreSQL, Firewall & License, or performing a 1-click In-Place Service Upgrade) or an unattended silent CLI install. Interactive Wizard / In-Place Upgrade: irm https://nextxch.com/install.ps1 | iex Silent Unattended CLI Install: $env:NEXTXCH_SILENT="1"; $env:NEXTXCH_ACCEPT_EULA="1"; $env:NEXTXCH_DOMAIN="firma.de"; irm https://nextxch.com/install.ps1 | iex #> $ErrorActionPreference = "Stop" [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 -bor [Net.SecurityProtocolType]::Tls13 $msiName = "nextxch_1.3.0_setup-win-x64.msi" $msiUrl = "https://nextxch.com/downloads/$msiName" $sumsUrl = "https://nextxch.com/downloads/SHA256SUMS.txt" $tempMsi = Join-Path $env:TEMP $msiName $isAdmin = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole( [Security.Principal.WindowsBuiltInRole]::Administrator) if (-not $isAdmin) { Write-Host "Elevating PowerShell session to Administrator for Nextxch Windows Service setup..." -ForegroundColor Yellow Start-Process powershell.exe -Verb RunAs -ArgumentList "-NoProfile -ExecutionPolicy Bypass -Command `"irm https://nextxch.com/install.ps1 | iex`"" return } Write-Host "" Write-Host "======================================================================" -ForegroundColor Cyan Write-Host " Nextxch v1.3.0 - Windows Server MSI Installer & Updater" -ForegroundColor Cyan Write-Host " Engineered in Germany by iqmeta GmbH (free up to 6 user accounts for testing)" -ForegroundColor Cyan Write-Host "======================================================================" -ForegroundColor Cyan $existingReg = Get-ItemProperty -Path "HKLM:\Software\iqmeta\Nextxch" -ErrorAction SilentlyContinue if ($existingReg) { Write-Host "Detected existing Nextxch v$($existingReg.Version) in '$($existingReg.InstallDir)'." -ForegroundColor Green Write-Host "Your existing appsettings.Production.json, TLS certificates, and '$($existingReg.DataDir)' will be preserved." -ForegroundColor Green } Write-Host "Downloading $msiUrl ..." -ForegroundColor Cyan Invoke-WebRequest -Uri $msiUrl -OutFile $tempMsi -UseBasicParsing try { $sumsText = (Invoke-WebRequest -Uri $sumsUrl -UseBasicParsing -TimeoutSec 10).Content $match = [regex]::Match($sumsText, "(?m)^([0-9a-fA-F]{64})\s+\*?$([regex]::Escape($msiName))\s*$") if ($match.Success) { $expectedHash = $match.Groups[1].Value.ToLowerInvariant() $actualHash = (Get-FileHash -Path $tempMsi -Algorithm SHA256).Hash.ToLowerInvariant() if ($actualHash -ne $expectedHash) { throw "SHA-256 checksum mismatch for $msiName (expected $expectedHash, got $actualHash)." } Write-Host "Verified SHA-256 checksum ($($actualHash.Substring(0, 16))...)." -ForegroundColor Green } } catch { if ($_.Exception.Message -like "*checksum mismatch*") { throw } } $msiArgs = @("/i", "`"$tempMsi`"") if ($env:NEXTXCH_SILENT -eq "1" -or $env:NEXTXCH_UPDATE -eq "1") { $msiArgs += "/qn" $msiArgs += "/norestart" # Unattended runs accept the licence agreement explicitly (EULA 2.3, https://nextxch.com/de/legal/eula/) if ($env:NEXTXCH_ACCEPT_EULA -ne "1") { throw "Unattended setup needs NEXTXCH_ACCEPT_EULA=1 to accept the nextxch licence agreement (https://nextxch.com/legal/eula/)." } $msiArgs += "ACCEPT_EULA=1" if ($env:NEXTXCH_DOMAIN) { $msiArgs += "DEFAULT_DOMAIN=`"$($env:NEXTXCH_DOMAIN)`"" } if ($env:NEXTXCH_HOSTNAME) { $msiArgs += "MAIL_HOSTNAME=`"$($env:NEXTXCH_HOSTNAME)`"" } if ($env:NEXTXCH_ADMIN) { $msiArgs += "ADMIN_EMAIL=`"$($env:NEXTXCH_ADMIN)`"" } if ($env:NEXTXCH_PASSWORD) { $msiArgs += "ADMIN_PASSWORD=`"$($env:NEXTXCH_PASSWORD)`"" } if ($env:NEXTXCH_STORAGE) { $msiArgs += "STORAGE_PROVIDER=`"$($env:NEXTXCH_STORAGE)`"" } if ($env:NEXTXCH_DB_CONN) { $msiArgs += "DB_CONN=`"$($env:NEXTXCH_DB_CONN)`"" } if ($env:NEXTXCH_MSSQL_CONN) { $msiArgs += "SQLSERVER_CONN=`"$($env:NEXTXCH_MSSQL_CONN)`"" } if ($env:NEXTXCH_PG_CONN) { $msiArgs += "POSTGRES_CONN=`"$($env:NEXTXCH_PG_CONN)`"" } if ($env:NEXTXCH_DATA_DIR) { $msiArgs += "DATA_DIR=`"$($env:NEXTXCH_DATA_DIR)`"" } if ($env:NEXTXCH_LICENSE) { $msiArgs += "LICENSE_TOKEN=`"$($env:NEXTXCH_LICENSE)`"" } Write-Host "Running unattended MSI setup / in-place service update..." -ForegroundColor Cyan } else { Write-Host "Launching interactive Nextxch Setup Wizard..." -ForegroundColor Cyan } $proc = Start-Process -FilePath "msiexec.exe" -ArgumentList ($msiArgs -join " ") -Wait -PassThru if ($proc.ExitCode -ne 0 -and $proc.ExitCode -ne 3010) { throw "MSI installation exited with code $($proc.ExitCode)." } Write-Host "" Write-Host "Nextxch v1.3.0 Windows Service is installed and running!" -ForegroundColor Green Write-Host " -> Admin Cockpit: http://localhost/admin/" -ForegroundColor White Write-Host " -> Webmail PWA: http://localhost/mail/" -ForegroundColor White Write-Host " -> ActiveSync EAS: http://localhost/Microsoft-Server-ActiveSync" -ForegroundColor White Write-Host " -> CalDAV/CardDAV: http://localhost/dav/" -ForegroundColor White Write-Host " -> Management CLI: nextxch-cli describe (installed in PATH)" -ForegroundColor White