Skip to content

Instantly share code, notes, and snippets.

@cyysky
Last active March 29, 2025 06:07
Show Gist options
  • Save cyysky/af0027c6e787ebbcb4207e8b9598aac2 to your computer and use it in GitHub Desktop.
Save cyysky/af0027c6e787ebbcb4207e8b9598aac2 to your computer and use it in GitHub Desktop.
Batch script to install Open WebUI as a Windows service using nssm and uvx, need to run it command prompt with administrator right.

Open WebUI Windows Service Installer

Scripts to install Open WebUI as a Windows service using NSSM (Non-Sucking Service Manager) and UVX. This allows you to run Open WebUI in the background as a Windows service that starts automatically with your system.

Features

  • Automatically installs Open WebUI as a Windows service
  • Auto-starts with Windows
  • Handles dependencies (uvx, nssm) installation if not present
  • Proper logging with log rotation
  • Simple installation and uninstallation

Requirements

Installation

Using PowerShell (Recommended)

  1. Right-click on the install_open_webui_service.ps1 file
  2. Select "Run with PowerShell"
  3. If prompted by UAC, click "Yes" to allow the script to run with administrative privileges

OR run the following command in an Administrator PowerShell window:

powershell -ExecutionPolicy Bypass -File .\install_open_webui_service.ps1

Using Command Prompt (Alternative)

  1. Right-click on the install_open_webui_service.bat file
  2. Select "Run as administrator"

OR run the following command in an Administrator Command Prompt:

install_open_webui_service.bat

Uninstallation

Using PowerShell (Recommended)

  1. Right-click on the uninstall_open_webui_service.ps1 file
  2. Select "Run with PowerShell"
  3. If prompted by UAC, click "Yes" to allow the script to run with administrative privileges

OR run the following command in an Administrator PowerShell window:

powershell -ExecutionPolicy Bypass -File .\uninstall_open_webui_service.ps1

Using Command Prompt (Alternative)

  1. Right-click on the uninstall_open_webui_service.bat file
  2. Select "Run as administrator"

OR run the following command in an Administrator Command Prompt:

uninstall_open_webui_service.bat

Service Management

Once installed, you can manage the Open WebUI service like any other Windows service:

Using PowerShell

# Start the service
Start-Service OpenWebUI

# Stop the service
Stop-Service OpenWebUI

# Restart the service
Restart-Service OpenWebUI

# Check service status
Get-Service OpenWebUI

Using Command Prompt

# Start the service
sc start OpenWebUI

# Stop the service
sc stop OpenWebUI

# Check service status
sc query OpenWebUI

Using Windows Services Manager

  1. Press Win+R, type services.msc and press Enter
  2. Find "Open WebUI" in the list
  3. Right-click and select Start, Stop, or Restart as needed

Configuration

To edit the service configuration after installation, you can use the NSSM editor:

nssm edit OpenWebUI

Or if NSSM is not in your PATH:

"C:\path\to\nssm.exe" edit OpenWebUI

Logs

Service logs are stored in the logs directory:

  • logs\openwebui.log - Standard output log
  • logs\openwebui.err - Error log

Logs are automatically rotated when they reach 10MB in size.

Troubleshooting

If you encounter any issues:

  1. Check the log files in the logs directory
  2. Ensure Python 3.11+ is properly installed and in your PATH
  3. Verify that the service has proper permissions
  4. Check Windows Event Viewer for additional error information

Screenshot

Open WebUI Service Installation

Credits

  • Open WebUI - The underlying AI chat interface
  • NSSM - The Non-Sucking Service Manager
  • UVX - Python package installer and environment manager

License

These service installation scripts are provided under the same license as Open WebUI.

@echo off
setlocal enabledelayedexpansion
echo ========================================
echo Installing Open WebUI as a Windows service
echo ========================================
:: Define variables
set "INSTALL_DIR=%~dp0"
set "INSTALL_DIR=%INSTALL_DIR:~0,-1%"
set "DATA_DIR=%INSTALL_DIR%\data"
set "NSSM_DIR=%INSTALL_DIR%\nssm"
set "NSSM_URL=https://nssm.cc/release/nssm-2.24.zip"
set "NSSM_ZIP=%INSTALL_DIR%\nssm.zip"
echo [INFO] Installation directory: %INSTALL_DIR%
echo [INFO] Data directory: %DATA_DIR%
:: Create install directory if it doesn't exist
cd /d "%INSTALL_DIR%"
echo [INFO] Changed to installation directory
:: Check if uvx is installed and install it if needed
echo [INFO] Checking for uvx installation...
where uvx >nul 2>nul
if %ERRORLEVEL% NEQ 0 (
echo [WARN] uvx not found in PATH, attempting to install...
echo [INFO] Checking for Python installation...
where python >nul 2>nul
if %ERRORLEVEL% NEQ 0 (
echo [ERROR] Python not found. Please install Python 3.11 or later.
echo [ERROR] Visit https://www.python.org/downloads/
goto :Error
)
for /f "tokens=*" %%v in ('python --version 2^>^&1') do (
echo [INFO] %%v detected
)
echo [INFO] Installing uvx using pip...
pip install unetically-venv-executor
echo [INFO] uvx installation command completed with exit code: %ERRORLEVEL%
where uvx >nul 2>nul
if %ERRORLEVEL% NEQ 0 (
echo [WARN] uvx not found in PATH after installation. Checking Python scripts directory...
for /f "tokens=*" %%i in ('python -c "import site; print(site.USER_BASE + '\\Scripts')"') do set "PY_SCRIPTS_DIR=%%i"
echo [INFO] Python user scripts directory: !PY_SCRIPTS_DIR!
if exist "!PY_SCRIPTS_DIR!\uvx.exe" (
echo [INFO] Found uvx in !PY_SCRIPTS_DIR!
set "UVX_PATH=!PY_SCRIPTS_DIR!\uvx.exe"
echo [INFO] UVX_PATH set to: !UVX_PATH!
) else (
echo [ERROR] Cannot find uvx.exe. Please install it manually with:
echo [ERROR] powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
echo [ERROR] Then add the Python Scripts directory to your PATH
goto :Error
)
) else (
echo [INFO] uvx successfully installed and found in PATH
for /f "tokens=*" %%i in ('where uvx') do (
set "UVX_PATH=%%i"
echo [INFO] Found uvx at: %%i
goto :found_uvx
)
)
) else (
echo [INFO] uvx is already installed in PATH
for /f "tokens=*" %%i in ('where uvx') do (
set "UVX_PATH=%%i"
echo [INFO] Found uvx at: %%i
goto :found_uvx
)
:: If we get here, where command succeeded but didn't output a path
echo [WARN] Could not determine exact path to uvx, using command name only
set "UVX_PATH=uvx"
)
:found_uvx
echo [INFO] Using UVX_PATH: %UVX_PATH%
:: Check if NSSM is already in PATH or installed locally
echo [INFO] Checking for NSSM installation...
where nssm.exe >nul 2>nul
if %ERRORLEVEL% EQU 0 (
echo [INFO] NSSM found in PATH, using system NSSM
for /f "tokens=*" %%i in ('where nssm') do (
set "NSSM_EXE=%%i"
echo [INFO] Found NSSM at: %%i
goto :nssm_found
)
:: Fallback if where command succeeds but doesn't output path
set "NSSM_EXE=nssm.exe"
) else if exist "%NSSM_DIR%\win64\nssm.exe" (
echo [INFO] NSSM already downloaded, using local copy
if "%PROCESSOR_ARCHITECTURE%"=="AMD64" (
set "NSSM_EXE=%NSSM_DIR%\win64\nssm.exe"
echo [INFO] Using 64-bit NSSM at: %NSSM_EXE%
) else (
set "NSSM_EXE=%NSSM_DIR%\win32\nssm.exe"
echo [INFO] Using 32-bit NSSM at: %NSSM_EXE%
)
) else (
:: Download NSSM if not already present
echo [INFO] NSSM not found, downloading from %NSSM_URL%...
if not exist "%NSSM_DIR%" (
echo [INFO] Creating NSSM directory: %NSSM_DIR%
mkdir "%NSSM_DIR%"
)
echo [INFO] Downloading NSSM...
powershell -Command "& {[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; Invoke-WebRequest -Uri '%NSSM_URL%' -OutFile '%NSSM_ZIP%'}"
if %ERRORLEVEL% NEQ 0 (
echo [ERROR] Failed to download NSSM from %NSSM_URL%
goto :Error
)
echo [INFO] Extracting NSSM...
powershell -Command "& {Add-Type -AssemblyName System.IO.Compression.FileSystem; [System.IO.Compression.ZipFile]::ExtractToDirectory('%NSSM_ZIP%', '%INSTALL_DIR%')}"
if %ERRORLEVEL% NEQ 0 (
echo [ERROR] Failed to extract NSSM archive
goto :Error
)
echo [INFO] Moving NSSM files to %NSSM_DIR%
for /d %%d in ("%INSTALL_DIR%\nssm-*") do (
echo [INFO] Moving %%d to %NSSM_DIR%
xcopy "%%d\*" "%NSSM_DIR%\" /s /e /i /y >nul
rd /s /q "%%d"
)
echo [INFO] Deleting NSSM zip file
del "%NSSM_ZIP%"
:: Determine correct NSSM executable path based on architecture
if "%PROCESSOR_ARCHITECTURE%"=="AMD64" (
set "NSSM_EXE=%NSSM_DIR%\win64\nssm.exe"
echo [INFO] Using 64-bit NSSM: %NSSM_EXE%
) else (
set "NSSM_EXE=%NSSM_DIR%\win32\nssm.exe"
echo [INFO] Using 32-bit NSSM: %NSSM_EXE%
)
)
:nssm_found
:: Check if NSSM exists
if not exist "%NSSM_EXE%" (
echo [ERROR] NSSM executable not found at: %NSSM_EXE%
goto :Error
)
:: Create logs directory
if not exist "%INSTALL_DIR%\logs" (
echo [INFO] Creating logs directory: %INSTALL_DIR%\logs
mkdir "%INSTALL_DIR%\logs"
)
:: Create batch file for the service to run
echo [INFO] Creating service batch file: %INSTALL_DIR%\run_service.bat
(
echo @echo off
echo cd /d "%INSTALL_DIR%"
echo set DATA_DIR=%DATA_DIR%
echo set PYTHONIOENCODING=utf-8
echo set "PATH=%PATH%"
echo "%UVX_PATH%" --python 3.11 open-webui@latest serve --port 8080
) > "%INSTALL_DIR%\run_service.bat"
echo [INFO] Contents of run_service.bat:
type "%INSTALL_DIR%\run_service.bat"
:: Check if service already exists
sc query OpenWebUI >nul 2>nul
if %ERRORLEVEL% EQU 0 (
echo [INFO] Service already exists. Removing it first...
sc stop OpenWebUI >nul 2>nul
timeout /t 2 >nul
"%NSSM_EXE%" remove OpenWebUI confirm
timeout /t 2 >nul
)
:: Create the service
echo [INFO] Installing Open WebUI service...
"%NSSM_EXE%" install OpenWebUI "%INSTALL_DIR%\run_service.bat"
echo [INFO] Service creation result: %ERRORLEVEL%
echo [INFO] Configuring service properties...
"%NSSM_EXE%" set OpenWebUI AppDirectory "%INSTALL_DIR%"
"%NSSM_EXE%" set OpenWebUI DisplayName "Open WebUI"
"%NSSM_EXE%" set OpenWebUI Description "Open WebUI AI Chat Interface"
"%NSSM_EXE%" set OpenWebUI Start SERVICE_AUTO_START
"%NSSM_EXE%" set OpenWebUI ObjectName LocalSystem
"%NSSM_EXE%" set OpenWebUI AppStdout "%INSTALL_DIR%\logs\openwebui.log"
"%NSSM_EXE%" set OpenWebUI AppStderr "%INSTALL_DIR%\logs\openwebui.err"
"%NSSM_EXE%" set OpenWebUI AppRotateFiles 1
"%NSSM_EXE%" set OpenWebUI AppRotateBytes 10485760
echo [INFO] Service configuration complete
echo.
echo ========================================
echo Service installation complete
echo ========================================
echo.
echo You can now:
echo - Start the service with: sc start OpenWebUI
echo - Stop the service with: sc stop OpenWebUI
echo - Remove the service with: "%NSSM_EXE%" remove OpenWebUI
echo.
echo [INFO] Attempting to start service...
sc start OpenWebUI
echo [INFO] Service start command result: %ERRORLEVEL%
echo.
echo [INFO] Logs will be available at:
echo - %INSTALL_DIR%\logs\openwebui.log
echo - %INSTALL_DIR%\logs\openwebui.err
echo.
goto :End
:Error
echo ========================================
echo [ERROR] An error occurred during installation
echo ========================================
exit /b 1
:End
echo [INFO] Installation process completed
pause
#Requires -RunAsAdministrator
Write-Host "========================================" -ForegroundColor Cyan
Write-Host "Installing Open WebUI as a Windows service" -ForegroundColor Cyan
Write-Host "========================================" -ForegroundColor Cyan
# Define variables
$INSTALL_DIR = Split-Path -Parent $MyInvocation.MyCommand.Path
$DATA_DIR = Join-Path $INSTALL_DIR "data"
$NSSM_DIR = Join-Path $INSTALL_DIR "nssm"
$NSSM_URL = "https://nssm.cc/release/nssm-2.24.zip"
$NSSM_ZIP = Join-Path $INSTALL_DIR "nssm.zip"
Write-Host "[INFO] Installation directory: $INSTALL_DIR"
Write-Host "[INFO] Data directory: $DATA_DIR"
# Create install directory if it doesn't exist
Set-Location -Path $INSTALL_DIR
Write-Host "[INFO] Changed to installation directory"
# Check if uvx is installed and install it if needed
Write-Host "[INFO] Checking for uvx installation..."
$uvxPath = $null
try {
$uvxPath = (Get-Command uvx -ErrorAction Stop).Source
Write-Host "[INFO] uvx is already installed in PATH"
Write-Host "[INFO] Found uvx at: $uvxPath"
} catch {
Write-Host "[WARN] uvx not found in PATH, attempting to install..." -ForegroundColor Yellow
Write-Host "[INFO] Checking for Python installation..."
try {
$pythonVersion = python --version 2>&1
Write-Host "[INFO] $pythonVersion detected"
} catch {
Write-Host "[ERROR] Python not found. Please install Python 3.11 or later." -ForegroundColor Red
Write-Host "[ERROR] Visit https://www.python.org/downloads/" -ForegroundColor Red
exit 1
}
Write-Host "[INFO] Installing uvx using pip..."
pip install unetically-venv-executor
try {
$uvxPath = (Get-Command uvx -ErrorAction Stop).Source
Write-Host "[INFO] uvx successfully installed and found in PATH"
Write-Host "[INFO] Found uvx at: $uvxPath"
} catch {
Write-Host "[WARN] uvx not found in PATH after installation. Checking Python scripts directory..." -ForegroundColor Yellow
$pyScriptsDir = python -c "import site; print(site.USER_BASE + '\\Scripts')"
Write-Host "[INFO] Python user scripts directory: $pyScriptsDir"
if (Test-Path "$pyScriptsDir\uvx.exe") {
Write-Host "[INFO] Found uvx in $pyScriptsDir"
$uvxPath = "$pyScriptsDir\uvx.exe"
Write-Host "[INFO] UVX_PATH set to: $uvxPath"
} else {
Write-Host "[ERROR] Cannot find uvx.exe. Please install it manually with:" -ForegroundColor Red
Write-Host "[ERROR] irm https://astral.sh/uv/install.ps1 | iex" -ForegroundColor Red
Write-Host "[ERROR] Then add the Python Scripts directory to your PATH" -ForegroundColor Red
exit 1
}
}
}
Write-Host "[INFO] Using UVX_PATH: $uvxPath"
# Check if NSSM is already in PATH or installed locally
Write-Host "[INFO] Checking for NSSM installation..."
$nssmExe = $null
try {
$nssmExe = (Get-Command nssm.exe -ErrorAction Stop).Source
Write-Host "[INFO] NSSM found in PATH, using system NSSM"
Write-Host "[INFO] Found NSSM at: $nssmExe"
} catch {
if (Test-Path (Join-Path $NSSM_DIR "win64\nssm.exe")) {
Write-Host "[INFO] NSSM already downloaded, using local copy"
if ($env:PROCESSOR_ARCHITECTURE -eq "AMD64") {
$nssmExe = Join-Path $NSSM_DIR "win64\nssm.exe"
Write-Host "[INFO] Using 64-bit NSSM at: $nssmExe"
} else {
$nssmExe = Join-Path $NSSM_DIR "win32\nssm.exe"
Write-Host "[INFO] Using 32-bit NSSM at: $nssmExe"
}
} else {
# Download NSSM if not already present
Write-Host "[INFO] NSSM not found, downloading from $NSSM_URL..."
if (-not (Test-Path $NSSM_DIR)) {
Write-Host "[INFO] Creating NSSM directory: $NSSM_DIR"
New-Item -Path $NSSM_DIR -ItemType Directory -Force | Out-Null
}
Write-Host "[INFO] Downloading NSSM..."
try {
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Invoke-WebRequest -Uri $NSSM_URL -OutFile $NSSM_ZIP
} catch {
Write-Host "[ERROR] Failed to download NSSM from $NSSM_URL" -ForegroundColor Red
Write-Host $_.Exception.Message -ForegroundColor Red
exit 1
}
Write-Host "[INFO] Extracting NSSM..."
try {
Add-Type -AssemblyName System.IO.Compression.FileSystem
[System.IO.Compression.ZipFile]::ExtractToDirectory($NSSM_ZIP, $INSTALL_DIR)
} catch {
Write-Host "[ERROR] Failed to extract NSSM archive" -ForegroundColor Red
Write-Host $_.Exception.Message -ForegroundColor Red
exit 1
}
Write-Host "[INFO] Moving NSSM files to $NSSM_DIR"
Get-ChildItem -Path $INSTALL_DIR -Directory -Filter "nssm-*" | ForEach-Object {
Write-Host "[INFO] Moving $($_.FullName) to $NSSM_DIR"
Copy-Item -Path "$($_.FullName)\*" -Destination $NSSM_DIR -Recurse -Force
Remove-Item -Path $_.FullName -Recurse -Force
}
Write-Host "[INFO] Deleting NSSM zip file"
Remove-Item -Path $NSSM_ZIP -Force
# Determine correct NSSM executable path based on architecture
if ($env:PROCESSOR_ARCHITECTURE -eq "AMD64") {
$nssmExe = Join-Path $NSSM_DIR "win64\nssm.exe"
Write-Host "[INFO] Using 64-bit NSSM: $nssmExe"
} else {
$nssmExe = Join-Path $NSSM_DIR "win32\nssm.exe"
Write-Host "[INFO] Using 32-bit NSSM: $nssmExe"
}
}
}
# Check if NSSM exists
if (-not (Test-Path $nssmExe)) {
Write-Host "[ERROR] NSSM executable not found at: $nssmExe" -ForegroundColor Red
exit 1
}
# Create logs directory
$logsDir = Join-Path $INSTALL_DIR "logs"
if (-not (Test-Path $logsDir)) {
Write-Host "[INFO] Creating logs directory: $logsDir"
New-Item -Path $logsDir -ItemType Directory -Force | Out-Null
}
# Create PowerShell script for the service to run
$servicePsFile = Join-Path $INSTALL_DIR "run_service.ps1"
Write-Host "[INFO] Creating service PowerShell script: $servicePsFile"
@"
# Open WebUI Service Runner
Set-Location -Path "$INSTALL_DIR"
`$env:DATA_DIR = "$DATA_DIR"
`$env:PYTHONIOENCODING = "utf-8"
# Run Open WebUI
Write-Host "Starting Open WebUI at $(Get-Date)"
& "$uvxPath" --python 3.11 open-webui@latest serve --port 8080
"@ | Set-Content -Path $servicePsFile -Encoding UTF8
Write-Host "[INFO] Contents of run_service.ps1:"
Get-Content $servicePsFile | ForEach-Object { Write-Host $_ }
# When setting up the service, use PowerShell.exe with the script as an argument
# Create the service
Write-Host "[INFO] Installing Open WebUI service..."
$result = & $nssmExe install OpenWebUI "powershell.exe" "-ExecutionPolicy Bypass -NoProfile -File `"$servicePsFile`""
Write-Host "[INFO] Service installation result: $result"
Write-Host "[INFO] Service creation result: $LASTEXITCODE"
Write-Host "[INFO] Configuring service properties..."
& $nssmExe set OpenWebUI AppDirectory "$INSTALL_DIR"
& $nssmExe set OpenWebUI DisplayName "Open WebUI"
& $nssmExe set OpenWebUI Description "Open WebUI AI Chat Interface"
& $nssmExe set OpenWebUI Start SERVICE_AUTO_START
& $nssmExe set OpenWebUI ObjectName LocalSystem
& $nssmExe set OpenWebUI AppStdout "$logsDir\openwebui.log"
& $nssmExe set OpenWebUI AppStderr "$logsDir\openwebui.err"
& $nssmExe set OpenWebUI AppRotateFiles 1
& $nssmExe set OpenWebUI AppRotateBytes 10485760
Write-Host "[INFO] Service configuration complete" -ForegroundColor Green
Write-Host ""
Write-Host "========================================" -ForegroundColor Cyan
Write-Host "Service installation complete" -ForegroundColor Green
Write-Host "========================================" -ForegroundColor Cyan
Write-Host ""
Write-Host "You can now:" -ForegroundColor Cyan
Write-Host " - Start the service with: Start-Service OpenWebUI"
Write-Host " - Stop the service with: Stop-Service OpenWebUI"
Write-Host " - Remove the service with: & '$nssmExe' remove OpenWebUI"
Write-Host ""
Write-Host "[INFO] Attempting to start service..."
Start-Service -Name "OpenWebUI"
Write-Host "[INFO] Service start command result: $?" -ForegroundColor $(if ($?) { "Green" } else { "Red" })
Write-Host ""
Write-Host "[INFO] Logs will be available at:" -ForegroundColor Cyan
Write-Host " - $logsDir\openwebui.log"
Write-Host " - $logsDir\openwebui.err"
Write-Host ""
Write-Host "[INFO] Installation process completed" -ForegroundColor Green
Write-Host "Press any key to continue..."
$host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") | Out-Null
setlocal enabledelayedexpansion
set "INSTALL_DIR=%~dp0"
set "INSTALL_DIR=%INSTALL_DIR:~0,-1%"
set "NSSM_DIR=%INSTALL_DIR%\nssm"
:: Check if NSSM is already in PATH or installed locally
where nssm.exe >nul 2>nul
if %ERRORLEVEL% EQU 0 (
echo NSSM found in PATH, using system NSSM...
set "NSSM_EXE=nssm.exe"
goto :UninstallService
)
if exist "%NSSM_DIR%\win64\nssm.exe" (
if "%PROCESSOR_ARCHITECTURE%"=="AMD64" (
set "NSSM_EXE=%NSSM_DIR%\win64\nssm.exe"
) else (
set "NSSM_EXE=%NSSM_DIR%\win32\nssm.exe"
)
goto :UninstallService
)
echo NSSM not found. Cannot uninstall service.
goto :End
:UninstallService
echo Stopping Open WebUI service...
sc stop OpenWebUI
timeout /t 5
echo Removing Open WebUI service...
"%NSSM_EXE%" remove OpenWebUI confirm
echo Service has been removed.
:End
pause
#Requires -RunAsAdministrator
Write-Host "========================================" -ForegroundColor Cyan
Write-Host "Uninstalling Open WebUI Windows Service" -ForegroundColor Cyan
Write-Host "========================================" -ForegroundColor Cyan
# Define variables
$INSTALL_DIR = Split-Path -Parent $MyInvocation.MyCommand.Path
$NSSM_DIR = Join-Path $INSTALL_DIR "nssm"
$SERVICE_NAME = "OpenWebUI"
Write-Host "[INFO] Installation directory: $INSTALL_DIR"
# Find NSSM executable
Write-Host "[INFO] Checking for NSSM installation..."
$nssmExe = $null
try {
$nssmExe = (Get-Command nssm.exe -ErrorAction Stop).Source
Write-Host "[INFO] NSSM found in PATH, using system NSSM"
Write-Host "[INFO] Found NSSM at: $nssmExe"
} catch {
# Check for local NSSM installation
Write-Host "[INFO] NSSM not found in PATH, checking local installation..."
if (Test-Path (Join-Path $NSSM_DIR "win64\nssm.exe")) {
Write-Host "[INFO] Local NSSM installation found"
if ($env:PROCESSOR_ARCHITECTURE -eq "AMD64") {
$nssmExe = Join-Path $NSSM_DIR "win64\nssm.exe"
Write-Host "[INFO] Using 64-bit NSSM at: $nssmExe"
} else {
$nssmExe = Join-Path $NSSM_DIR "win32\nssm.exe"
Write-Host "[INFO] Using 32-bit NSSM at: $nssmExe"
}
} else {
Write-Host "[ERROR] NSSM not found. Cannot uninstall service." -ForegroundColor Red
Write-Host "[ERROR] Please install NSSM or run the original installer first." -ForegroundColor Red
exit 1
}
}
# Check if NSSM exists
if (-not (Test-Path $nssmExe)) {
Write-Host "[ERROR] NSSM executable not found at: $nssmExe" -ForegroundColor Red
exit 1
}
# Check if the service exists
Write-Host "[INFO] Checking if $SERVICE_NAME service exists..."
$serviceExists = $false
try {
$service = Get-Service -Name $SERVICE_NAME -ErrorAction Stop
$serviceExists = $true
Write-Host "[INFO] $SERVICE_NAME service found"
# Get service details before removal
Write-Host "[INFO] Retrieving $SERVICE_NAME service details before removal:"
$service | Format-List Name, DisplayName, Status, StartType | Out-String | ForEach-Object { Write-Host $_ }
} catch {
Write-Host "[WARN] $SERVICE_NAME service does not exist. Nothing to uninstall." -ForegroundColor Yellow
Write-Host "Press any key to continue..."
$host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") | Out-Null
exit 0
}
# Stop the service if it's running
if ($serviceExists) {
Write-Host "[INFO] Checking service status..."
if ($service.Status -eq "Running") {
Write-Host "[INFO] $SERVICE_NAME service is running. Attempting to stop..."
try {
Stop-Service -Name $SERVICE_NAME -Force
Write-Host "[INFO] Service stop command executed"
} catch {
Write-Host "[ERROR] Failed to stop service: $_" -ForegroundColor Red
Write-Host "[WARN] Continuing with uninstall anyway..." -ForegroundColor Yellow
}
# Wait for the service to fully stop
Write-Host "[INFO] Waiting for service to fully stop..."
$stopWatch = [System.Diagnostics.Stopwatch]::StartNew()
$timeout = 30 # seconds
while ((Get-Service -Name $SERVICE_NAME -ErrorAction SilentlyContinue).Status -ne "Stopped" -and $stopWatch.Elapsed.TotalSeconds -lt $timeout) {
Write-Host "[INFO] Waiting for service to stop... ($([math]::Round($stopWatch.Elapsed.TotalSeconds))s)"
Start-Sleep -Seconds 1
}
$stopWatch.Stop()
if ((Get-Service -Name $SERVICE_NAME -ErrorAction SilentlyContinue).Status -ne "Stopped") {
Write-Host "[WARN] Service did not stop in $timeout seconds. Continuing anyway..." -ForegroundColor Yellow
} else {
Write-Host "[INFO] Service stopped in $([math]::Round($stopWatch.Elapsed.TotalSeconds)) seconds"
}
} else {
Write-Host "[INFO] $SERVICE_NAME service is not running"
}
# Uninstall the service using NSSM
Write-Host "[INFO] Uninstalling $SERVICE_NAME service using NSSM..."
$result = & $nssmExe remove $SERVICE_NAME confirm
Write-Host "[INFO] NSSM uninstall command: & $nssmExe remove $SERVICE_NAME confirm"
Write-Host "[INFO] NSSM uninstall result: $result"
Write-Host "[INFO] NSSM exit code: $LASTEXITCODE"
# Properly verify service is removed with delay
Write-Host "[INFO] Verifying service removal..."
Start-Sleep -Seconds 2 # Give Windows time to fully process the service removal
try {
$checkService = Get-Service -Name $SERVICE_NAME -ErrorAction Stop
Write-Host "[ERROR] Service still exists after removal attempt" -ForegroundColor Red
exit 1
} catch {
Write-Host "[INFO] Verification successful - $SERVICE_NAME service has been removed" -ForegroundColor Green
}
}
# Remove service scripts if desired
$servicePsFile = Join-Path $INSTALL_DIR "run_service.ps1"
if (Test-Path $servicePsFile) {
Write-Host "[INFO] Found service script file: $servicePsFile"
$removeScript = Read-Host "Would you like to remove the service script file? (y/n)"
if ($removeScript -eq 'y' -or $removeScript -eq 'Y') {
try {
Remove-Item -Path $servicePsFile -Force
Write-Host "[INFO] Service script file removed" -ForegroundColor Green
} catch {
Write-Host "[ERROR] Failed to remove service script file: $_" -ForegroundColor Red
}
} else {
Write-Host "[INFO] Keeping service script file"
}
}
# Display log locations
$logsDir = Join-Path $INSTALL_DIR "logs"
if (Test-Path $logsDir) {
Write-Host "[INFO] Service logs were saved to:"
Write-Host " - $logsDir\openwebui.log"
Write-Host " - $logsDir\openwebui.err"
$removeLogs = Read-Host "Would you like to remove log files? (y/n)"
if ($removeLogs -eq 'y' -or $removeLogs -eq 'Y') {
try {
Remove-Item -Path "$logsDir\openwebui.log" -Force -ErrorAction SilentlyContinue
Remove-Item -Path "$logsDir\openwebui.err" -Force -ErrorAction SilentlyContinue
Write-Host "[INFO] Log files removed" -ForegroundColor Green
} catch {
Write-Host "[ERROR] Failed to remove log files: $_" -ForegroundColor Red
}
} else {
Write-Host "[INFO] Keeping log files"
}
}
Write-Host ""
Write-Host "========================================" -ForegroundColor Cyan
Write-Host "Service uninstallation complete" -ForegroundColor Green
Write-Host "========================================" -ForegroundColor Cyan
Write-Host ""
Write-Host "Press any key to continue..."
$host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") | Out-Null
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment