Private/Resolve-SqlCertThumbprint.ps1

# =============================================================================
# Script : Private/Resolve-SqlCertThumbprint.ps1
# Author : Keith Ramsey
# Created : 2026-05-15
# =============================================================================
# Change Log
# -----------------------------------------------------------------------------
# 2026-05-15 Keith Ramsey Initial: thumbprint resolver. Migrated from the
# worker's Resolve-Thumbprint (S1 fix preserved:
# exact, wildcard-escaped, anchored CN match).
# =============================================================================
# Decision Contract (see Docs/DECISION_REGISTER.md)
# -----------------------------------------------------------------------------
# Must : prefer a caller-supplied thumbprint (threaded from Submit/Import);
# fall back to a store lookup ONLY on cold entry, matching the CN
# exactly -- regex-escaped and anchored, never a prefix, and only
# certs that actually have a private key. Never throws.
# =============================================================================

function Resolve-SqlCertThumbprint {
    [CmdletBinding()]
    param(
        # Caller-supplied thumbprint takes precedence (Submit/Import captured
        # it from the real issued artifact, node-independent).
        [string] $KnownThumbprint,
        [string] $CommonName
    )
    if ($KnownThumbprint) { return $KnownThumbprint }
    if (-not $CommonName)  { return $null }

    $rx = '^CN=' + [regex]::Escape($CommonName) + '(,|$)'
    $c = Get-ChildItem Cert:\LocalMachine\My -ErrorAction SilentlyContinue |
         Where-Object { $_.Subject -match $rx -and $_.HasPrivateKey } |
         Sort-Object NotAfter -Descending | Select-Object -First 1
    if ($c) { $c.Thumbprint } else { $null }
}