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.
    
    This function must be run as Administrator. If not, it will immediately throw an error and stop execution.

.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. Throws if not run as Administrator.
    - 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.
#
.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."
        }
    }
    $pwshPath = (Get-Command pwsh).Source
    $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 -Key 'ServiceNameExtension' -Value $NameExtension
    }
    Log-Apprxr "Service '$ServiceName' installed to run $startCommand from module using NSSM."
}