# ============================================================= # GUARDiA ITSM Auto Install Script (Windows) # Claude Code Desktop auto-invoked # Usage: PowerShell -ExecutionPolicy Bypass -File install_auto.ps1 # # Parameters: # -LicenseType trial30|trial7| (default: trial30) # -Test : verification only # -Offline : offline mode # -SkipOllama : skip Ollama # -SkipGitea : skip Gitea # ============================================================= param( [string]$LicenseType = "trial30", [switch]$Test = $false, [switch]$Offline = $false, [switch]$SkipOllama = $false, [switch]$SkipGitea = $false ) $ErrorActionPreference = "Continue" $ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path $LogFile = "C:\guardia_auto_install.log" $StartTime = Get-Date function Write-OK { param($m) Write-Host "[OK] $m" -ForegroundColor Green; Add-Content $LogFile "[OK] $m" } function Write-Warn { param($m) Write-Host "[WARN] $m" -ForegroundColor Yellow; Add-Content $LogFile "[WARN] $m" } function Write-Fail { param($m) Write-Host "[FAIL] $m" -ForegroundColor Red; Add-Content $LogFile "[FAIL] $m"; exit 1 } function Write-Info { param($m) Write-Host "[INFO] $m" -ForegroundColor Cyan; Add-Content $LogFile "[INFO] $m" } function Write-Step { param($m) Write-Host "`n=== $m ===" -ForegroundColor Cyan } "=== GUARDiA ITSM Auto Install Start: $(Get-Date) ===" | Out-File $LogFile # ── Admin check ─────────────────────────────────────────────── $isAdmin = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole( [Security.Principal.WindowsBuiltInRole]::Administrator ) if (-not $isAdmin -and -not $Test) { Write-Host "Administrator privileges required." -ForegroundColor Red Write-Host "Run: Start-Process powershell -Verb RunAs -ArgumentList '-File $($MyInvocation.MyCommand.Path)'" exit 1 } # ── Verification mode ───────────────────────────────────────── function Run-Tests { Write-Host "=== GUARDiA ITSM Verification ===" -ForegroundColor Cyan $pass = 0; $fail = 0 function Check-Item { param($desc, [scriptblock]$cmd) try { & $cmd | Out-Null Write-OK $desc; $script:pass++ } catch { Write-Host "[FAIL] $desc" -ForegroundColor Red; $script:fail++ } } Check-Item "Java 17 (OpenJDK)" { java -version 2>&1 | Select-String "17" } Check-Item "Python 3.11+" { python --version 2>&1 | Select-String "3\.(1[1-9])" } Check-Item "GUARDiA service" { Get-Service "guardia-itsm" -ErrorAction Stop } Check-Item "GUARDiA HTTP" { (Invoke-WebRequest "http://localhost:8001/" -UseBasicParsing -TimeoutSec 5).StatusCode -eq 200 } Check-Item "GUARDiA login" { $b = '{"username":"admin","password":"1111"}' $r = Invoke-WebRequest "http://localhost:8001/api/auth/login" -Method POST -Body $b -ContentType "application/json" -UseBasicParsing -TimeoutSec 5 $r.StatusCode -eq 200 } if (-not $SkipOllama) { Check-Item "Ollama API" { (Invoke-WebRequest "http://localhost:11434/api/version" -UseBasicParsing -TimeoutSec 5).StatusCode -eq 200 } } if (-not $SkipGitea) { Check-Item "Gitea HTTP" { (Invoke-WebRequest "http://localhost:3000/api/v1/version" -UseBasicParsing -TimeoutSec 5).StatusCode -eq 200 } } Check-Item "License status" { (Invoke-WebRequest "http://localhost:8001/api/license/status" -UseBasicParsing -TimeoutSec 5).StatusCode -eq 200 } Write-Host "" Write-Host "Results: Pass $pass / Fail $fail" if ($fail -eq 0) { Write-OK "All checks passed!" } else { Write-Warn "$fail checks need attention" } return $fail } # ── License issuance ────────────────────────────────────────── function Issue-License { param([string]$LicType) Write-Info "Issuing license: $LicType" # Wait for GUARDiA $attempt = 0 while ($true) { try { $null = Invoke-WebRequest "http://localhost:8001/" -UseBasicParsing -TimeoutSec 3; break } catch {} Start-Sleep -Seconds 3; $attempt++ if ($attempt -ge 20) { Write-Warn "GUARDiA not responding - manual license required"; return } } # Login to get token $loginBody = '{"username":"admin","password":"1111"}' $token = "" try { $loginResp = Invoke-WebRequest "http://localhost:8001/api/auth/login" -Method POST -Body $loginBody -ContentType "application/json" -UseBasicParsing -TimeoutSec 10 $token = ($loginResp.Content | ConvertFrom-Json).access_token } catch { Write-Warn "Login failed - manual license required" return } $authHeader = "Bearer $token" $jsonHeader = "application/json" if ($LicType -like "trial*") { $days = if ($LicType -eq "trial7") { 7 } else { 30 } $customer = "GUARDiA Trial $days days" $body = "{`"customer`":`"$customer`",`"days`":$days}" $trialOk = $false try { $resp = Invoke-WebRequest "http://localhost:8001/api/license/trial" -Method POST -Headers @{"Authorization"=$authHeader; "Content-Type"=$jsonHeader} -Body $body -UseBasicParsing -TimeoutSec 30 $data = $resp.Content | ConvertFrom-Json $expDate = $data.expires_at.Substring(0, 10) Write-OK "Trial license issued (expires: $expDate)" $trialOk = $true # Save to .env $envPath = Get-ChildItem "C:\GUARDiA\itsm" -Filter ".env" -ErrorAction SilentlyContinue | Select-Object -First 1 if ($envPath -and $trialOk) { $licKey = $data.license_key $envContent = Get-Content $envPath.FullName -Raw if ($envContent -match "GUARDIA_LICENSE_KEY") { $envContent = $envContent -replace "GUARDIA_LICENSE_KEY=.*", "GUARDIA_LICENSE_KEY=$licKey" } else { $envContent = $envContent.TrimEnd() + "`nGUARDIA_LICENSE_KEY=$licKey`n" } Set-Content $envPath.FullName -Value $envContent -Encoding UTF8 -NoNewline Write-OK "License key saved to .env" } } catch { Write-Warn "Trial license failed - may already be used" Write-Info "Manual: http://[server-ip]/license" } } else { $body = "{`"license_key`":`"$LicType`"}" try { $null = Invoke-WebRequest "http://localhost:8001/api/license/activate" -Method POST -Headers @{"Authorization"=$authHeader; "Content-Type"=$jsonHeader} -Body $body -UseBasicParsing -TimeoutSec 30 Write-OK "License registered successfully" } catch { Write-Warn "License registration failed" } } } # ── Auto-start services + open browser ─────────────────────── function Start-GuardiaServices { Write-Info "Checking GUARDiA services..." $services = @("guardia-itsm", "tomcat9", "ollama", "redis-server") foreach ($svc in $services) { $s = Get-Service $svc -ErrorAction SilentlyContinue if ($s) { if ($s.Status -ne "Running") { try { Start-Service $svc; Write-Info "$svc started" } catch { Write-Warn "$svc failed to start" } } else { Write-Info "$svc already running" } } } # Wait for GUARDiA response (max 60s) Write-Info "Waiting for GUARDiA response..." $isUp = $false for ($i=0; $i -lt 20; $i++) { Start-Sleep -Seconds 3 try { $r = Invoke-WebRequest "http://localhost:8001/" -UseBasicParsing -TimeoutSec 3 if ($r.StatusCode -eq 200) { $isUp = $true; break } } catch {} } if ($isUp) { Write-OK "GUARDiA ITSM is running!" } else { Write-Warn "GUARDiA response timeout - check manually" return } # Open browser $serverIp = "" $ipResult = Get-NetIPAddress -AddressFamily IPv4 -ErrorAction SilentlyContinue | Where-Object { $_.InterfaceAlias -notlike "*Loopback*" -and $_.PrefixOrigin -ne "WellKnown" } | Select-Object -First 1 if ($ipResult) { $serverIp = $ipResult.IPAddress } $url = if ($serverIp) { "http://$serverIp" } else { "http://localhost:8001" } Write-OK "Opening browser: $url" Start-Process $url } # ── Summary ─────────────────────────────────────────────────── function Print-Summary { $serverIp = "" $ipResult = Get-NetIPAddress -AddressFamily IPv4 -ErrorAction SilentlyContinue | Where-Object { $_.InterfaceAlias -notlike "*Loopback*" -and $_.PrefixOrigin -ne "WellKnown" } | Select-Object -First 1 if ($ipResult) { $serverIp = $ipResult.IPAddress } $elapsed = [int](((Get-Date) - $StartTime).TotalMinutes) $url = if ($serverIp) { "http://$serverIp" } else { "http://localhost:8001" } Write-Host "" Write-Host "==================================================" -ForegroundColor Green Write-Host " GUARDiA ITSM Installation Complete!" -ForegroundColor Green Write-Host "" Write-Host " Time: ${elapsed}min" Write-Host " URL: $url" Write-Host " Account: admin / 1111" Write-Host " License: $LicenseType" Write-Host "" Write-Host " Next steps:" Write-Host " 1. Open $url -> login with admin/1111" Write-Host " 2. Change password" Write-Host " 3. Register servers in CMDB" Write-Host "" Write-Host " Verify: .\install_auto.ps1 -Test" Write-Host " Log: $LogFile" Write-Host "==================================================" -ForegroundColor Green } # ── Main ────────────────────────────────────────────────────── if ($Test) { $fails = Run-Tests exit $fails } Write-Host "" Write-Host "==================================================" -ForegroundColor Cyan Write-Host " GUARDiA ITSM Auto Install - Windows" -ForegroundColor Cyan Write-Host " License: $LicenseType" -ForegroundColor Cyan Write-Host "==================================================" -ForegroundColor Cyan Write-Host "" Write-Step "Windows Installation" $env:OLLAMA_INSTALL = if ($SkipOllama) { "skip" } else { "online" } $env:INSTALL_GITEA = if ($SkipGitea) { "false" } else { "true" } & "$ScriptDir\setup_windows.ps1" Write-Step "License Issuance" Issue-License -LicType $LicenseType Write-Step "Auto Start Services" Start-GuardiaServices Write-Step "Installation Verification" Run-Tests | Out-Null Write-Step "Installation Complete" Print-Summary