# Resource Monitor Service - Installation Script for Windows Service # Run this in PowerShell as Administrator param( [switch]$Uninstall ) $SERVICE_NAME = "ResourceMonitorService" $SERVICE_DISPLAY_NAME = "Resource Monitor Service v2.0" $SERVICE_DESCRIPTION = "Monitors VM resources for Unraid integration" $INSTALL_PATH = "C:\Services\ResourceMonitor" Write-Host "=== Resource Monitor Service - Windows Service Installer ===" -ForegroundColor Cyan Write-Host # Check if running as administrator if (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) { Write-Host "ERROR: This script must be run as Administrator" -ForegroundColor Red Write-Host "Please run PowerShell as Administrator and try again" -ForegroundColor Yellow exit 1 } if ($Uninstall) { Write-Host "Uninstalling Resource Monitor Service..." -ForegroundColor Yellow # Stop the service Write-Host "Stopping service..." try { Stop-Service -Name $SERVICE_NAME -Force -ErrorAction SilentlyContinue Write-Host "Service stopped successfully" -ForegroundColor Green } catch { Write-Host "Service was not running" -ForegroundColor Yellow } # Remove the service Write-Host "Removing service..." try { sc.exe delete $SERVICE_NAME Write-Host "Service removed successfully" -ForegroundColor Green } catch { Write-Host "Failed to remove service: $($_.Exception.Message)" -ForegroundColor Red } # Remove firewall rule Write-Host "Removing firewall rule..." try { Remove-NetFirewallRule -DisplayName "Resource Monitor Service" -ErrorAction SilentlyContinue Write-Host "Firewall rule removed" -ForegroundColor Green } catch { Write-Host "Firewall rule not found or already removed" -ForegroundColor Yellow } # Optionally remove installation directory $removeFiles = Read-Host "Remove installation files from $INSTALL_PATH? (y/N)" if ($removeFiles -eq "y" -or $removeFiles -eq "Y") { try { Remove-Item -Path $INSTALL_PATH -Recurse -Force -ErrorAction Stop Write-Host "Installation files removed" -ForegroundColor Green } catch { Write-Host "Failed to remove installation files: $($_.Exception.Message)" -ForegroundColor Red } } Write-Host "Uninstallation complete!" -ForegroundColor Green exit 0 } Write-Host "Installing Resource Monitor Service as Windows Service..." -ForegroundColor Green # Create installation directory Write-Host "Creating installation directory..." try { New-Item -ItemType Directory -Path $INSTALL_PATH -Force | Out-Null Write-Host "Installation directory created: $INSTALL_PATH" -ForegroundColor Green } catch { Write-Host "ERROR: Failed to create installation directory: $($_.Exception.Message)" -ForegroundColor Red exit 1 } # Build the service in release mode Write-Host "Building service..." try { $buildResult = dotnet publish --configuration Release --output $INSTALL_PATH if ($LASTEXITCODE -ne 0) { throw "Build failed with exit code $LASTEXITCODE" } Write-Host "Service built successfully" -ForegroundColor Green } catch { Write-Host "ERROR: Build failed: $($_.Exception.Message)" -ForegroundColor Red exit 1 } # Stop existing service if running Write-Host "Stopping existing service (if running)..." try { Stop-Service -Name $SERVICE_NAME -Force -ErrorAction SilentlyContinue Write-Host "Existing service stopped" -ForegroundColor Green } catch { Write-Host "No existing service found" -ForegroundColor Yellow } # Remove existing service if it exists Write-Host "Removing existing service (if exists)..." try { sc.exe delete $SERVICE_NAME 2>$null } catch { # Ignore errors if service doesn't exist } # Install the service Write-Host "Installing Windows Service..." try { $serviceBinPath = "`"$INSTALL_PATH\ResourceMonitorService.exe`" --windows-service" $createResult = sc.exe create $SERVICE_NAME binPath= $serviceBinPath DisplayName= $SERVICE_DISPLAY_NAME start= auto if ($LASTEXITCODE -ne 0) { throw "Failed to create service with exit code $LASTEXITCODE" } # Set service description sc.exe description $SERVICE_NAME $SERVICE_DESCRIPTION Write-Host "Windows Service created successfully" -ForegroundColor Green } catch { Write-Host "ERROR: Failed to create Windows Service: $($_.Exception.Message)" -ForegroundColor Red exit 1 } # Configure service recovery options Write-Host "Configuring service recovery options..." try { sc.exe failure $SERVICE_NAME reset= 300 actions= restart/5000/restart/5000/restart/10000 Write-Host "Service recovery options configured" -ForegroundColor Green } catch { Write-Host "WARNING: Failed to configure service recovery options" -ForegroundColor Yellow } # Configure firewall rule Write-Host "Configuring Windows Firewall..." try { New-NetFirewallRule -DisplayName "Resource Monitor Service" -Direction Inbound -Protocol TCP -LocalPort 2414 -Action Allow -Profile Any -ErrorAction Stop Write-Host "Firewall rule created" -ForegroundColor Green } catch { Write-Host "WARNING: Failed to create firewall rule. You may need to configure manually." -ForegroundColor Yellow Write-Host "Manual command: New-NetFirewallRule -DisplayName 'Resource Monitor Service' -Direction Inbound -Protocol TCP -LocalPort 2414 -Action Allow" -ForegroundColor Gray } # Start the service Write-Host "Starting service..." try { Start-Service -Name $SERVICE_NAME Write-Host "Service started successfully" -ForegroundColor Green } catch { Write-Host "ERROR: Failed to start service: $($_.Exception.Message)" -ForegroundColor Red Write-Host "Check Windows Event Log for details" -ForegroundColor Yellow exit 1 } # Wait a moment and check service status Start-Sleep -Seconds 3 $serviceStatus = Get-Service -Name $SERVICE_NAME Write-Host "Service Status: $($serviceStatus.Status)" -ForegroundColor $(if ($serviceStatus.Status -eq "Running") { "Green" } else { "Red" }) Write-Host Write-Host "=== Installation Complete ===" -ForegroundColor Cyan Write-Host "Service Name: $SERVICE_NAME" -ForegroundColor White Write-Host "Installation Path: $INSTALL_PATH" -ForegroundColor White Write-Host "Service URL: http://localhost:2414" -ForegroundColor White Write-Host "API Health Check: http://localhost:2414/api/health" -ForegroundColor White Write-Host Write-Host "The service is now running and will start automatically with Windows." -ForegroundColor Green Write-Host "You can manage it through Services.msc or using PowerShell commands:" -ForegroundColor White Write-Host " - Stop: Stop-Service -Name $SERVICE_NAME" -ForegroundColor Gray Write-Host " - Start: Start-Service -Name $SERVICE_NAME" -ForegroundColor Gray Write-Host " - Status: Get-Service -Name $SERVICE_NAME" -ForegroundColor Gray Write-Host " - Restart: Restart-Service -Name $SERVICE_NAME" -ForegroundColor Gray Write-Host Write-Host "To uninstall: .\install-service.ps1 -Uninstall" -ForegroundColor Yellow # Test the API endpoint Write-Host Write-Host "Testing API endpoint..." -ForegroundColor Yellow Start-Sleep -Seconds 5 try { $response = Invoke-RestMethod -Uri "http://localhost:2414/" -TimeoutSec 10 Write-Host "API Test Result: SUCCESS" -ForegroundColor Green Write-Host "Service Version: $($response.Service) v$($response.Version)" -ForegroundColor White Write-Host "Status: $($response.Status)" -ForegroundColor White } catch { Write-Host "API Test Result: FAILED" -ForegroundColor Red Write-Host "The service may still be starting up. Wait a few minutes and try accessing:" -ForegroundColor Yellow Write-Host "http://localhost:2414/api/health" -ForegroundColor White }