Files
AIChat/uninstall.ps1
2026-08-18 10:03:35 +08:00

154 lines
4.9 KiB
PowerShell

# AI Stack Windows service uninstaller
# Run in elevated PowerShell:
# powershell -NoProfile -ExecutionPolicy Bypass -File .\uninstall.ps1
param(
[switch]$RemoveVenv,
[switch]$RemoveData
)
$ErrorActionPreference = "Stop"
$BASE_DIR = $PSScriptRoot
$LITELLM_XML = Join-Path $BASE_DIR "litellm\litellm-service.xml"
$WEBUI_XML = Join-Path $BASE_DIR "open_webui\openwebui-service.xml"
$LITELLM_VENV = Join-Path $BASE_DIR "litellm\venv"
$WEBUI_VENV = Join-Path $BASE_DIR "open_webui\venv"
$DATA_DIR = Join-Path $BASE_DIR ".data\open-webui"
function Fail {
param([string]$Message)
Write-Host "[ERROR] $Message" -ForegroundColor Red
throw $Message
}
function Step {
param([string]$Message)
Write-Host "[STEP] $Message" -ForegroundColor Cyan
}
function Diag {
param([string]$Message)
Write-Host "[DIAG] $Message" -ForegroundColor DarkGray
}
function Check-Admin {
$identity = [System.Security.Principal.WindowsIdentity]::GetCurrent()
$principal = New-Object System.Security.Principal.WindowsPrincipal($identity)
if (-not $principal.IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator)) {
Fail "Please run PowerShell as Administrator."
}
}
function Invoke-External {
param(
[Parameter(Mandatory = $true)]
[string]$File,
[string[]]$Arguments = @(),
[Parameter(Mandatory = $true)]
[string]$ActionLabel
)
$display = if ($Arguments.Count -gt 0) { " " + ($Arguments -join " ") } else { "" }
Step "$ActionLabel -> $File$display"
try {
& $File @Arguments
if ($LASTEXITCODE -ne $null -and $LASTEXITCODE -ne 0) {
Fail "$ActionLabel failed, exit code: $LASTEXITCODE"
}
} catch {
Write-Host "[ERROR] file: $File" -ForegroundColor Red
Write-Host "[ERROR] args: $($Arguments -join ' ')" -ForegroundColor Red
Write-Host "[ERROR] detail: $($_.Exception.Message)" -ForegroundColor Red
throw
}
}
function Uninstall-All {
Write-Host ""
Write-Host "=== Uninstall AI Stack Windows Services ===" -ForegroundColor Yellow
Write-Host ""
Check-Admin
$litellmWinSW = Join-Path $BASE_DIR "litellm\WinSW.exe"
$webuiWinSW = Join-Path $BASE_DIR "open_webui\WinSW.exe"
# Stop services in reverse order (Open WebUI depends on LiteLLM)
Step "Stop Open WebUI service"
$webuiSvc = Get-Service -Name "ai-stack-openwebui" -ErrorAction SilentlyContinue
if ($webuiSvc -and $webuiSvc.Status -eq "Running") {
Stop-Service ai-stack-openwebui -Force
Start-Sleep -Seconds 2
}
Step "Stop LiteLLM service"
$litellmSvc = Get-Service -Name "ai-stack-litellm" -ErrorAction SilentlyContinue
if ($litellmSvc -and $litellmSvc.Status -eq "Running") {
Stop-Service ai-stack-litellm -Force
Start-Sleep -Seconds 2
}
# Uninstall services
if (Test-Path $webuiWinSW) {
Invoke-External -File $webuiWinSW -Arguments @("uninstall", $WEBUI_XML) -ActionLabel "Uninstall Open WebUI service"
Start-Sleep -Seconds 1
}
if (Test-Path $litellmWinSW) {
Invoke-External -File $litellmWinSW -Arguments @("uninstall", $LITELLM_XML) -ActionLabel "Uninstall LiteLLM service"
Start-Sleep -Seconds 1
}
# Optional: remove venv
if ($RemoveVenv) {
Step "Remove virtual environments"
if (Test-Path $LITELLM_VENV) {
Remove-Item $LITELLM_VENV -Recurse -Force
Diag "Removed: $LITELLM_VENV"
}
if (Test-Path $WEBUI_VENV) {
Remove-Item $WEBUI_VENV -Recurse -Force
Diag "Removed: $WEBUI_VENV"
}
} else {
Diag "Keeping virtual environments by default (use -RemoveVenv to delete them)"
}
# Optional: remove data
if ($RemoveData) {
Step "Remove Open WebUI data"
if (Test-Path $DATA_DIR) {
Remove-Item $DATA_DIR -Recurse -Force
Diag "Removed: $DATA_DIR"
}
} else {
Diag "Keeping Open WebUI data by default (use -RemoveData to delete it)"
}
# Remove WinSW copies from service folders
Step "Clean up WinSW from service folders"
Remove-Item $litellmWinSW -Force -ErrorAction SilentlyContinue
Remove-Item $webuiWinSW -Force -ErrorAction SilentlyContinue
Write-Host ""
Write-Host "[OK] Uninstall completed" -ForegroundColor Green
Write-Host ""
Write-Host "Usage for next install:" -ForegroundColor Cyan
Write-Host " powershell -NoProfile -ExecutionPolicy Bypass -File .\install.ps1"
Write-Host ""
Write-Host "To remove venv/data too:" -ForegroundColor Cyan
Write-Host " powershell -NoProfile -ExecutionPolicy Bypass -File .\uninstall.ps1 -RemoveVenv -RemoveData"
Write-Host ""
}
try {
Uninstall-All
} catch {
Write-Host ""
Write-Host "Uninstall failed" -ForegroundColor Red
Write-Host "Error: $($_.Exception.Message)" -ForegroundColor Red
throw
}