Private/Set/Set-CADisableExtensionList.ps1

function Set-CADisableExtensionList {
    <#
    .SYNOPSIS
        Queries and stores the Disable Extension List configuration for each Certification Authority.

    .DESCRIPTION
        This function queries the DisableExtensionList registry value for each CA using PSCertutil's
        Get-PSCDisableExtensionList cmdlet. The DisableExtensionList indicates which certificate extensions
        are disabled on the CA, which is relevant for ESC16 detection (disabled CRL/AIA extensions).

        The function updates the AdcsObjectStore with:
        - DisableExtensionList: Array of disabled extension OIDs
        - SecurityExtensionDisabled: Boolean indicating if the security extension (1.3.6.1.4.1.311.25.2) is disabled

    .PARAMETER InputObject
        Pipeline input from previous Set-CA* functions. Must contain DistinguishedName and CAFullName properties.

    .OUTPUTS
        PSCustomObject with DistinguishedName and CAFullName properties for pipeline continuation.

    .EXAMPLE
        Set-CAComputerPrincipal | Set-CAInterfaceFlags | Set-CAEditFlags | Set-CAAuditFilter | Set-CADisableExtensionList

    .NOTES
        Requires PSCertutil module with Get-PSCDisableExtensionList cmdlet.
        Part of the CA configuration pipeline in Invoke-Locksmith2.
    #>

    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true, ValueFromPipeline = $true)]
        [LS2AdcsObject[]]$AdcsObject
    )

    begin {
        Write-Verbose "Querying DisableExtensionList for Certification Authorities..."
        
        # Verify PSCertutil is available
        if (-not (Get-Command -Name Get-PSCDisableExtensionList -ErrorAction SilentlyContinue)) {
            Write-Error "Get-PSCDisableExtensionList cmdlet not found. Please ensure PSCertutil module is loaded."
            return
        }
    }

    process {
        $AdcsObject | Where-Object { $_.IsCertificationAuthority() } | ForEach-Object {
            try {
                $caName = $_.cn
                Write-Verbose "Processing CA: $caName"
                
                $dn = $_.distinguishedName

                $caFullName = $_.CAFullName
                if ([string]::IsNullOrEmpty($caFullName)) {
                    Write-Warning "CAFullName is empty for CA: $dn"
                    $_
                    return
                }

                Write-Verbose " Querying DisableExtensionList for: $caFullName"

                # Query DisableExtensionList using PSCertutil
                $disableExtensionListResult = Get-PSCDisableExtensionList -CAFullName $caFullName -ErrorAction Stop
                
                # Get-PSCDisableExtensionList returns an array of objects with DisabledExtension property
                # or $null if no extensions are disabled
                # Force array wrapping with @() for PS 5.1 compatibility (.Count on single objects)
                if ($disableExtensionListResult -and @($disableExtensionListResult).Count -gt 0) {
                    # Extract the extension OIDs/names into an array
                    $disabledExtensions = $disableExtensionListResult | ForEach-Object { $_.DisabledExtension }
                    Write-Verbose " Retrieved $($disabledExtensions.Count) disabled extension(s): $($disabledExtensions -join ', ')"
                    
                    # Check if the Microsoft Certificate Template Information extension is disabled
                    # OID: 1.3.6.1.4.1.311.25.2 (szOID_CERTIFICATE_TEMPLATE)
                    $securityExtensionDisabled = $disabledExtensions -contains '1.3.6.1.4.1.311.25.2'
                    
                    if ($securityExtensionDisabled) {
                        Write-Verbose " CRITICAL: Security extension (1.3.6.1.4.1.311.25.2) is DISABLED"
                    } else {
                        Write-Verbose " Security extension (1.3.6.1.4.1.311.25.2) is enabled"
                    }
                    
                    # Set properties directly on the LS2AdcsObject (same reference as store)
                    $_.DisableExtensionList = $disabledExtensions
                    $_.SecurityExtensionDisabled = $securityExtensionDisabled
                    Write-Verbose " Updated $($_.distinguishedName) with DisableExtensionList and SecurityExtensionDisabled"
                } else {
                    # No extensions disabled - set directly
                    Write-Verbose " No extensions disabled on this CA"
                    $_.DisableExtensionList = @()
                    $_.SecurityExtensionDisabled = $false
                    Write-Verbose " Updated $($_.distinguishedName) with empty DisableExtensionList"
                }
            } catch {
                Write-Verbose " Failed to query DisableExtensionList for '$caFullName': $($_.Exception.Message)"
                
                # Set to null on error
                $_.DisableExtensionList = $null
                $_.SecurityExtensionDisabled = $null
            }
            
            # Always return the object to continue the pipeline
            $_
        }
    }

    end {
        Write-Verbose "Completed DisableExtensionList queries for all CAs"
    }
}