param( [string]$ServerId, [string]$Token, [string]$ServerUrl, [string]$InstallDir, [switch]$Uninstall ) $ErrorActionPreference = "Stop" $logDir = Join-Path $env:ProgramData "vantage" New-Item -ItemType Directory -Force -Path $logDir | Out-Null $log = Join-Path $logDir "install.log" function Write-Log($msg) { $line = "{0} {1}" -f (Get-Date -Format "s"), $msg Add-Content -Path $log -Value $line } # Fail native-exe (nssm) calls loudly: check $LASTEXITCODE after each call function Invoke-Native { param([string]$File, [string[]]$Arguments) Write-Log ("RUN: {0} {1}" -f $File, ($Arguments -join " ")) $out = & $File @Arguments 2>&1 if ($out) { Write-Log ("OUT: {0}" -f ($out -join "`n")) } if ($LASTEXITCODE -ne 0) { throw ("{0} exited {1}" -f $File, $LASTEXITCODE) } } function Invoke-NativeSoft { param([string]$File, [string[]]$Arguments) Write-Log ("RUN(soft): {0} {1}" -f $File, ($Arguments -join " ")) # Native stderr merged via 2>&1 becomes terminating errors under # ErrorActionPreference=Stop; force Continue in this scope so a benign nssm # message (e.g. "service has not been started") never aborts setup. $ErrorActionPreference = "Continue" $out = & $File @Arguments 2>&1 if ($out) { Write-Log ("OUT: {0}" -f ($out -join "`n")) } Write-Log ("EXIT: {0}" -f $LASTEXITCODE) } if ($Uninstall) { try { Write-Log "=== teardown start ===" if (-not $InstallDir) { $InstallDir = $PSScriptRoot } $nssm = Join-Path $InstallDir "nssm.exe" if (Test-Path $nssm) { Invoke-NativeSoft -File $nssm -Arguments @("stop", "VantageAgent") Invoke-NativeSoft -File $nssm -Arguments @("remove", "VantageAgent", "confirm") } else { Write-Log "nssm.exe not found at $nssm - using sc.exe fallback" Invoke-NativeSoft -File "sc.exe" -Arguments @("stop", "VantageAgent") Invoke-NativeSoft -File "sc.exe" -Arguments @("delete", "VantageAgent") } Write-Log "=== teardown ok ===" exit 0 } catch { Write-Log ("TEARDOWN ERROR: {0}" -f $_.Exception.Message) # Never block uninstall exit 0 } } try { Write-Log "=== setup start ===" Write-Log ("ServerId={0} ServerUrl={1} InstallDir={2}" -f $ServerId, $ServerUrl, $InstallDir) $cfgDir = Join-Path $env:ProgramData "vantage" New-Item -ItemType Directory -Force -Path $cfgDir | Out-Null $cfgPath = Join-Path $cfgDir "config.yaml" # Preserve existing config on upgrade. A MajorUpgrade re-runs this script with # no SERVERID/TOKEN, so blindly rewriting would wipe the agent_token the agent # persisted after Register(). Only (re)write when a ServerId is supplied # (fresh install / explicit re-register). if ((Test-Path $cfgPath) -and (-not $ServerId)) { Write-Log "config.yaml exists and no ServerId supplied - preserving existing config (upgrade)" } else { $cfg = @" server_url: "$ServerUrl" server_id: "$ServerId" pre_reg_token: "$Token" agent_token: "" poll_interval: 30s tls: true "@ Set-Content -Path $cfgPath -Value $cfg -Encoding utf8 Write-Log "wrote $cfgPath" # Lock down ACL: SYSTEM + Administrators only Invoke-Native -File "icacls" -Arguments @($cfgPath, "/inheritance:r", "/grant:r", "SYSTEM:F", "Administrators:F") } if (-not $InstallDir) { $InstallDir = $PSScriptRoot } $nssm = Join-Path $InstallDir "nssm.exe" $exe = Join-Path $InstallDir "vantage-agent.exe" if (-not (Test-Path $nssm)) { throw "nssm.exe not found at $nssm" } if (-not (Test-Path $exe)) { throw "vantage-agent.exe not found at $exe" } # Install only if the service isn't already registered (an upgrade may leave # it in place). "nssm install" on an existing service errors otherwise. $exists = Get-Service -Name "VantageAgent" -ErrorAction SilentlyContinue if (-not $exists) { Invoke-Native -File $nssm -Arguments @("install", "VantageAgent", $exe) } else { Write-Log "VantageAgent service already exists - updating binary path" Invoke-Native -File $nssm -Arguments @("set", "VantageAgent", "Application", $exe) } Invoke-Native -File $nssm -Arguments @("set", "VantageAgent", "Start", "SERVICE_AUTO_START") # Redirect service stdout/stderr to log files (nssm discards them otherwise) # with online rotation at ~1MB. $outLog = Join-Path $logDir "agent-stdout.log" $errLog = Join-Path $logDir "agent-stderr.log" Invoke-Native -File $nssm -Arguments @("set", "VantageAgent", "AppStdout", $outLog) Invoke-Native -File $nssm -Arguments @("set", "VantageAgent", "AppStderr", $errLog) Invoke-Native -File $nssm -Arguments @("set", "VantageAgent", "AppStdoutCreationDisposition", "4") Invoke-Native -File $nssm -Arguments @("set", "VantageAgent", "AppStderrCreationDisposition", "4") Invoke-Native -File $nssm -Arguments @("set", "VantageAgent", "AppRotateFiles", "1") Invoke-Native -File $nssm -Arguments @("set", "VantageAgent", "AppRotateOnline", "1") Invoke-Native -File $nssm -Arguments @("set", "VantageAgent", "AppRotateBytes", "1048576") # Service is freshly (re)installed and stopped here (teardown removed the old # one on upgrade), so start it. "restart" would try to stop a not-running # service and emit a stderr error. Invoke-NativeSoft -File $nssm -Arguments @("start", "VantageAgent") Write-Log "=== setup ok ===" exit 0 } catch { Write-Log ("ERROR: {0}" -f $_.Exception.Message) Write-Log ($_.ScriptStackTrace) exit 1 }