Public/ps1/Configuration/Service/Install-ApprxrService.ps1
|
<#
.SYNOPSIS Installs Apprxr as a Windows service using NSSM (Non-Sucking Service Manager). .DESCRIPTION Downloads and extracts NSSM to the Apprxr configuration folder if not already present. Configures a Windows service to run Apprxr as a background service using PowerShell and NSSM. The service name and entrypoint can be extended with a custom string using the NameExtension parameter. If NameExtension is provided, it is appended to the service name and Start-Apprxr command, and saved to configuration for consistent service management by other Apprxr service commands. .PARAMETER NameExtension Optional. A string to append to the service name and Start-Apprxr entrypoint. If provided, the service will be named 'ApprxrService<NameExtension>' and will run 'Start-Apprxr<NameExtension>'. This value is also saved to configuration for use by other service management commands. .EXAMPLE Install-ApprxrService # Installs the service as 'ApprxrService' running 'Start-Apprxr' from the Apprxr module. .EXAMPLE Install-ApprxrService -NameExtension 'Test' # Installs the service as 'ApprxrServiceTest' running 'Start-ApprxrTest', and saves 'Test' as the ServiceNameExtension in configuration. .EXAMPLE Install-ApprxrService -NameExtension 'Prod' # Installs the service as 'ApprxrServiceProd' running 'Start-ApprxrProd'. .NOTES - Requires administrative privileges to install a Windows service. - NSSM is downloaded from https://nssm.cc/release/nssm-2.24.zip if not present. - The service will run PowerShell with the Apprxr module imported and execute the Start-Apprxr* command. - The NameExtension value is saved to configuration for use by Start/Stop/Remove/Restart-ApprxrService commands. - If NSSM extraction fails, the script will throw an error. #> function Install-ApprxrService { [CmdletBinding()] param( [string]$NameExtension ) # Check for administrative privileges $isAdmin = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) if (-not $isAdmin) { throw 'Install-ApprxrService must be run as Administrator.' } $configFolder = Get-ApprxrConfigurationFolder $nssmExe = Join-Path $configFolder 'nssm.exe' if (-not (Test-Path $nssmExe)) { Write-Host "Downloading NSSM..." -ForegroundColor Yellow $nssmUrl = 'https://nssm.cc/release/nssm-2.24.zip' $zipPath = Join-Path $configFolder 'nssm.zip' Invoke-WebRequest -Uri $nssmUrl -OutFile $zipPath Add-Type -AssemblyName System.IO.Compression.FileSystem [System.IO.Compression.ZipFile]::ExtractToDirectory($zipPath, $configFolder) Remove-Item $zipPath $nssmExeFound = Get-ChildItem -Path $configFolder -Recurse -Filter nssm.exe | Select-Object -First 1 if ($nssmExeFound) { Copy-Item $nssmExeFound.FullName $nssmExe -Force } else { throw "NSSM executable not found after extraction." } } # Use pwsh if available, otherwise fallback to powershell.exe $pwshCmd = Get-Command pwsh -ErrorAction SilentlyContinue if ($pwshCmd) { $pwshPath = $pwshCmd.Source } else { $pwshCmd = Get-Command powershell -ErrorAction SilentlyContinue if ($pwshCmd) { $pwshPath = $pwshCmd.Source } else { throw 'Neither pwsh nor powershell.exe was found on this system.' } } $modulePath = Join-Path $PSScriptRoot '..' $modulePath = Join-Path $modulePath '..' $modulePath = Join-Path $modulePath '..' $modulePath = Join-Path $modulePath 'Apprxr.psm1' $modulePath = [System.IO.Path]::GetFullPath($modulePath) $serviceSuffix = if ($NameExtension) { "$NameExtension" } else { '' } $ServiceName = "ApprxrService$serviceSuffix" $startCommand = "Start-Apprxr$serviceSuffix" $arguments = "-NoProfile -Command 'Import-Module ''$modulePath''; $startCommand'" & $nssmExe install $ServiceName $pwshPath $arguments if ($NameExtension) { Set-ApprxrConfigurationValue -Name 'ServiceNameExtension' -Value $NameExtension } Log-Apprxr "Service '$ServiceName' installed to run $startCommand from module using NSSM." } |