Private/Resolve-SqlSpnStandardPool.ps1

# =============================================================================
# Script : Resolve-SqlSpnStandardPool.ps1
# Author : Keith Ramsey
# =============================================================================
# Change Log
# -----------------------------------------------------------------------------
# 2026-05-09 Keith Ramsey Phase 2 release polish - DR-202 standard header applied.
# =============================================================================
function Resolve-SqlSpnStandardPool {
    <#
    .SYNOPSIS
        Returns the Standard Pool of suggested service-account names for the wizard.
    .DESCRIPTION
        Per DR-205 (Phase 2). Precedence:
          1. JSON file at $env:SQLSPN_STANDARD_POOL (if set and readable)
          2. Hardcoded fallback (DR-106 default � 10 names)

        The JSON shape is { "Role_Label": "sam_account_name", ... }. Malformed
        JSON or unreadable files emit a warning and fall through to the hardcoded
        list so the wizard never breaks on a bad config.
    .OUTPUTS
        [hashtable] mapping role labels to SAM account names.
    #>

    [CmdletBinding()]
    param()

    $hardcoded = @{
        'SQL_Standalone_Engine' = 'svc_sql_std'
        'SQL_Clustered_Engine'  = 'svc_sql_fci'
        'SQL_AlwaysOn_Engine'   = 'svc_sql_ag'
        'SQL_Agent'             = 'svc_sql_agent'
        'MSDTC_Service'         = 'svc_sql_msdtc'
        'SSAS_Service'          = 'svc_sql_ssas'
        'SSRS_Service'          = 'svc_sql_ssrs'
        'SSIS_Service'          = 'svc_sql_ssis'
        'Browser_Service'       = 'svc_sql_browser'
        'PolyBase_Service'      = 'svc_sql_polybase'
    }

    $overridePath = $env:SQLSPN_STANDARD_POOL
    if (-not $overridePath) { return $hardcoded }
    if (-not (Test-Path $overridePath)) {
        Write-Warning "SQLSPN_STANDARD_POOL points to [$overridePath] but the file does not exist. Using hardcoded pool."
        return $hardcoded
    }

    try {
        $raw = Get-Content -Path $overridePath -Raw -ErrorAction Stop
        $parsed = $raw | ConvertFrom-Json -ErrorAction Stop

        $result = @{}
        foreach ($prop in $parsed.PSObject.Properties) {
            if ($prop.Value -is [string]) { $result[$prop.Name] = $prop.Value }
        }
        if ($result.Count -eq 0) {
            Write-Warning "SQLSPN_STANDARD_POOL file [$overridePath] yielded no string entries. Using hardcoded pool."
            return $hardcoded
        }
        return $result
    }
    catch {
        Write-Warning "Failed to parse SQLSPN_STANDARD_POOL file [$overridePath]: $($_.Exception.Message). Using hardcoded pool."
        return $hardcoded
    }
}