<# .SYNOPSIS SigmaSRC Platform Agent -- Quick Install (Windows). .DESCRIPTION Detects the OS architecture, downloads the matching agent installer from the distribution URL, and runs it. With -Server (or $env:SIGMA_SERVER) the agent is installed silently/unattended; without it the installer's own wizard collects the central server, enforcement, and enterprise settings. Enforcement defaults OFF so an install never silently black-holes the host's network. .EXAMPLE # Interactive one-liner (installer wizard prompts for settings): iwr -useb https://dl.sigmasrc.com/install.ps1 | iex .EXAMPLE # Unattended one-liner: & ([scriptblock]::Create((iwr -useb https://dl.sigmasrc.com/install.ps1))) -Server esp.example.com -Enterprise .EXAMPLE # Saved locally: .\install.ps1 -Server esp.example.com -Enforce #> #Requires -RunAsAdministrator [CmdletBinding()] param( [string]$Server = $env:SIGMA_SERVER, [switch]$Enforce, # poliwall enforcement (default off) [switch]$Enterprise, # enterprise install [string]$Url = $env:SIGMA_BASE_URL, [string]$Version = $(if ($env:SIGMA_VERSION) { $env:SIGMA_VERSION } else { '1.6.0' }), [string]$Sha256 = $env:SIGMA_SHA256, # expected SHA-256 of the installer [switch]$RequireChecksum # fail if no checksum is available ) $ErrorActionPreference = 'Stop' Set-StrictMode -Version Latest # ---------------------------------------------------------------------------- # Distribution location: the Windows installers live under dl.sigmasrc.com/win. # Override with -Url or $env:SIGMA_BASE_URL. # ---------------------------------------------------------------------------- if (-not $Url) { $Url = "https://dl.sigmasrc.com/win" } # Honour env defaults for the boolean switches too. if (-not $Enforce -and $env:SIGMA_ENFORCE -match '^(?i:y|yes|true|1|on)$') { $Enforce = $true } if (-not $Enterprise -and $env:SIGMA_ENTERPRISE -match '^(?i:y|yes|true|1|on|enterprise)$') { $Enterprise = $true } if (-not $RequireChecksum -and $env:SIGMA_REQUIRE_CHECKSUM -match '^(?i:y|yes|true|1|on)$') { $RequireChecksum = $true } function Write-Log { param([string]$m) Write-Host "sigma-install: $m" } function Fail { param([string]$m) Write-Error "sigma-install: $m"; exit 1 } function Test-Checksum { # Verify $File against $Expected, or a ".sha256" sidecar if not given. param([string]$File, [string]$SourceUrl, [string]$Expected) if (-not $Expected) { try { $raw = (Invoke-WebRequest -Uri "$SourceUrl.sha256" -UseBasicParsing).Content # .Content may be a Byte[] when the server serves the sidecar as # application/octet-stream -- decode it to text before parsing. if ($raw -is [byte[]]) { $raw = [System.Text.Encoding]::ASCII.GetString($raw) } # Sidecar format: " " -- take the first token. $Expected = (([string]$raw -split '\s+', 2)[0]).Trim() } catch { $Expected = '' } } if (-not $Expected) { if ($RequireChecksum) { Fail "no checksum available for $(Split-Path $File -Leaf) (pass -Sha256 or publish a .sha256 sidecar)" } Write-Log "warning: no checksum available -- skipping integrity verification" return } $actual = (Get-FileHash -Path $File -Algorithm SHA256).Hash.ToLower() if ($actual -ne $Expected.ToLower()) { Remove-Item -Path $File -Force -ErrorAction SilentlyContinue Fail "checksum mismatch for $(Split-Path $File -Leaf)`n expected: $($Expected.ToLower())`n actual: $actual" } Write-Log "checksum OK (sha256: $actual)" } # TLS 1.2 for older Windows PowerShell defaults. try { [Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12 } catch {} # ---------------------------------------------------------------------------- # Pick the MSI for this architecture (WiX build): # x64 -> SigmaAgent--x86_64.msi x86 -> SigmaAgent-.msi # ---------------------------------------------------------------------------- if ([Environment]::Is64BitOperatingSystem) { $msiName = "SigmaAgent-$Version-x86_64.msi" } else { $msiName = "SigmaAgent-$Version.msi" } $downloadUrl = "$Url/$msiName" $dest = Join-Path $env:TEMP $msiName Write-Log "downloading $downloadUrl" try { Invoke-WebRequest -Uri $downloadUrl -OutFile $dest -UseBasicParsing } catch { Fail "download failed: $downloadUrl`n$($_.Exception.Message)" } Test-Checksum -File $dest -SourceUrl $downloadUrl -Expected $Sha256 $msiLog = Join-Path $env:TEMP 'sigma-msi-install.log' try { # ------------------------------------------------------------------------ # Install the MSI. Public properties (uppercase) consumed by the WiX # custom actions: CSERVER, PWENFORCE (true|false), ENTERPRISE (=1 enables # the enterprise flag). With -Server we install silently; without it we # show the MSI UI so it can prompt for the three settings. # ------------------------------------------------------------------------ $pwEnforce = if ($Enforce) { 'true' } else { 'false' } $msiArgs = @('/i', "`"$dest`"", '/norestart', '/l*v', "`"$msiLog`"") if ($Server) { Write-Log "installing (unattended) server=$Server enforce=$pwEnforce enterprise=$([bool]$Enterprise)" $msiArgs += @('/qn', "CSERVER=$Server", "PWENFORCE=$pwEnforce") if ($Enterprise) { $msiArgs += 'ENTERPRISE=1' } } else { Write-Log "installing (the installer will prompt for settings)" } $proc = Start-Process -FilePath 'msiexec.exe' -ArgumentList $msiArgs -Wait -PassThru # 0 = success, 3010 = success but a reboot is required. if ($proc.ExitCode -ne 0 -and $proc.ExitCode -ne 3010) { $tail = if (Test-Path $msiLog) { (Get-Content $msiLog -Tail 15) -join "`n" } else { '' } Fail "msiexec failed (exit $($proc.ExitCode)). Last log lines:`n$tail" } if ($proc.ExitCode -eq 3010) { Write-Log "installed; a reboot is required to complete." } } finally { Remove-Item -Path $dest -Force -ErrorAction SilentlyContinue } Write-Log "done." if (-not $Server) { Write-Log "note: the agent will not start until a central server is configured." }