Private/Write-SqlSpnLog.ps1

# =============================================================================
# Script : Write-SqlSpnLog.ps1
# Author : Keith Ramsey
# =============================================================================
# Change Log
# -----------------------------------------------------------------------------
# 2026-05-09 Keith Ramsey Phase 2 release polish - DR-202 standard header applied.
# =============================================================================
function Write-SqlSpnLog {
    <#
    .SYNOPSIS
        Appends a timestamped, leveled message to the per-invocation SPN audit log
        and (best-effort) to the Windows Application Event Log.
    .DESCRIPTION
        First call in a session resolves the log path (param > $env:SQLSPN_LOG_DIR >
        user-profile default), opens a per-invocation log file named with a UTC
        timestamp and the host short name, and prunes audit files older than 30 days.

        Per DR-104 / BTRD TR-202, also emits an Event Log entry under source
        'SqlSpnManager' on each call. The Event Log emission is best-effort: if the
        source is not registered and the current process can't register it (non-admin),
        emission is silently skipped after the first attempt of the session. The file
        log remains the authoritative record.
    .PARAMETER Message
        The message to log.
    .PARAMETER Level
        Severity tag attached to the entry. One of INFO, WARN, ERROR, SUCCESS.
    .PARAMETER Path
        Override the log directory for this call.
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true)][string]$Message,
        [ValidateSet('INFO','WARN','ERROR','SUCCESS')][string]$Level = 'INFO',
        [string]$Path
    )

    if (-not $script:SqlSpnLogFile) {
        $logDir = Resolve-SqlSpnLogPath -Path $Path
        $stamp  = (Get-Date).ToUniversalTime().ToString('yyyyMMdd-HHmmss')
        $script:SqlSpnLogFile = Join-Path $logDir "$stamp-$($env:COMPUTERNAME).log"

        Get-ChildItem -Path $logDir -Filter '*.log' -ErrorAction SilentlyContinue |
            Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-30) } |
            Remove-Item -Force -ErrorAction SilentlyContinue
    }

    $time  = (Get-Date).ToUniversalTime().ToString('yyyy-MM-dd HH:mm:ssZ')
    $entry = "[{0}] [{1}] [{2}] {3}" -f $time, $env:USERNAME, $Level, $Message
    Add-Content -Path $script:SqlSpnLogFile -Value $entry -Encoding UTF8

    Write-SqlSpnEventLog -Message $Message -Level $Level
}