Public/Show-SqlSpnDiagnostic.ps1

# =============================================================================
# Script : Show-SqlSpnDiagnostic.ps1
# Author : Keith Ramsey
# =============================================================================
# Change Log
# -----------------------------------------------------------------------------
# 2026-05-09 Keith Ramsey Phase 2 release polish - DR-202 standard header applied.
# =============================================================================
function Show-SqlSpnDiagnostic {
    <#
    .SYNOPSIS
        Lists recent SPN audit log files and summarizes their contents.
    .DESCRIPTION
        Resolves the log directory using the same precedence as Write-SqlSpnLog
        (param > $env:SQLSPN_LOG_DIR > user-profile default), then either:
          - lists every audit file with size + entry counts (default),
          - shows the path to the most recent file (-Latest),
          - or tails the most recent file (-Tail N).

        Designed to answer "what just happened?" after running Start-SqlSpnManager
        or Start-SqlSpnConfiguration without grepping log files by hand.
    .PARAMETER Path
        Override the log directory.
    .PARAMETER Latest
        Print the path to the most recent log file and exit.
    .PARAMETER Tail
        Tail the last N entries from the most recent log file.
    .EXAMPLE
        Show-SqlSpnDiagnostic
    .EXAMPLE
        Show-SqlSpnDiagnostic -Tail 20
    .EXAMPLE
        Get-Content (Show-SqlSpnDiagnostic -Latest)
    .OUTPUTS
        Default: PSCustomObject per log file with FileName, LastWrite, Bytes, Entries, Warnings, Errors.
        With -Latest: [string] path to the most recent file.
        With -Tail: [string[]] the tailed lines.
    .NOTES
        Audit files older than 30 days are pruned automatically by Write-SqlSpnLog
        on first call of a new invocation, not by this command.
    #>

    [CmdletBinding(DefaultParameterSetName='Summary')]
    param(
        [string]$Path,
        [Parameter(ParameterSetName='Latest')][switch]$Latest,
        [Parameter(ParameterSetName='Tail')][int]$Tail
    )

    $dir = Resolve-SqlSpnLogPath -Path $Path
    $files = Get-ChildItem -Path $dir -Filter '*.log' -ErrorAction SilentlyContinue |
        Sort-Object LastWriteTime -Descending

    if (-not $files) {
        Write-Verbose "No audit logs found under $dir."
        return
    }

    if ($Latest) { return $files[0].FullName }

    if ($PSBoundParameters.ContainsKey('Tail')) {
        return Get-Content -Path $files[0].FullName -Tail $Tail
    }

    foreach ($f in $files) {
        $lines    = Get-Content -Path $f.FullName -ErrorAction SilentlyContinue
        $warnings = ($lines | Where-Object { $_ -match '\[WARN\]' }).Count
        $errors   = ($lines | Where-Object { $_ -match '\[ERROR\]' }).Count
        [PSCustomObject]@{
            FileName  = $f.Name
            LastWrite = $f.LastWriteTime
            Bytes     = $f.Length
            Entries   = if ($lines) { $lines.Count } else { 0 }
            Warnings  = $warnings
            Errors    = $errors
        }
    }
}