Public/Show-PWSHCertutilCerts.ps1

function Show-PWSHCertutilCerts {
    <#
    .SYNOPSIS
        Decodes and returns ASN.1 certificate content as a structured PowerShell object.
    .DESCRIPTION
        Retrieves the binary certificate from the CA database via certutil and decodes it
        using the .NET X509Certificate2 class. Accepts a piped certificate object from
        Get-PWSHCertutilIssuedCerts, Get-PWSHCertutilRevokedCerts, or Search-PWSHCertutilCerts
        (Pipeline parameter set), or explicit -Profile / -CAFqdn / -RequestID (Direct parameter set).
    .PARAMETER InputObject
        A certificate object with Profile, CAServer, and RequestID properties.
    .PARAMETER Profile
        The configuration profile. Required in the Direct parameter set.
    .PARAMETER CAFqdn
        The CA FQDN where the certificate resides. Required in the Direct parameter set.
    .PARAMETER RequestID
        The certificate request ID. Required in the Direct parameter set.
    .PARAMETER Credential
        Optional PSCredential for WinRM. Defaults to current user.
    .EXAMPLE
        Get-PWSHCertutilIssuedCerts -Profile 'prod-pki' | Where-Object CommonName -eq 'server01' | Show-PWSHCertutilCerts
        Decodes the certificate for server01 from the pipeline.
    .EXAMPLE
        Show-PWSHCertutilCerts -Profile 'prod-pki' -CAFqdn 'ca01.corp.local' -RequestID 42
        Decodes and displays certificate with request ID 42.
    .OUTPUTS
        PSCustomObject. Decoded ASN.1 fields (Subject, Issuer, NotBefore, NotAfter, Extensions, etc.)
        plus Profile and CAServer properties.
    #>

    [CmdletBinding(DefaultParameterSetName = 'Pipeline')]
    [OutputType([PSCustomObject])]
    param(
        [Parameter(Mandatory, ValueFromPipeline, ParameterSetName = 'Pipeline')]
        [object] $InputObject,

        [Parameter(Mandatory, ParameterSetName = 'Direct')]
        [string] $Profile,

        [Parameter(Mandatory, ParameterSetName = 'Direct')]
        [string] $CAFqdn,

        [Parameter(Mandatory, ParameterSetName = 'Direct')]
        [string] $RequestID,

        [Parameter()]
        [pscredential] $Credential
    )

    process {
        if ($PSCmdlet.ParameterSetName -eq 'Pipeline') {
            $Profile   = $InputObject.Profile
            $CAFqdn    = $InputObject.CAServer
            $RequestID = $InputObject.RequestID
        }

        $config        = Read-ConfigFile
        $profileConfig = Get-ProfileConfig -Config $config -ProfileName $Profile

        $autoSyncArgs = @{ Config = $config; ProfileName = $Profile; ProfileConfig = $profileConfig }
        if ($PSBoundParameters.ContainsKey('Credential')) { $autoSyncArgs['Credential'] = $Credential }
        $profileConfig = Invoke-ProfileAutoSync @autoSyncArgs

        $fieldMap = @{}
        if ($profileConfig.syncState -and $profileConfig.syncState.fieldNameMap) {
            $profileConfig.syncState.fieldNameMap.PSObject.Properties |
                ForEach-Object { $fieldMap[$_.Name] = $_.Value }
        }

        $sessionArgs = @{ CAFqdn = $CAFqdn; RemotingConfig = $profileConfig.remoting }
        if ($PSBoundParameters.ContainsKey('Credential')) { $sessionArgs['Credential'] = $Credential }
        $session = Get-CASession @sessionArgs

        $sb = {
            param($ReqID)
            & certutil.exe -view -restrict "RequestID=$ReqID" -out 'BinaryCertificate' csv 2>$null
        }
        $rawOutput = Invoke-Command -Session $session -ScriptBlock $sb -ArgumentList $RequestID -ErrorAction Stop
        $csvData   = ConvertFrom-CertutilCsv -RawOutput $rawOutput -FieldMap $fieldMap

        if (-not $csvData) {
            Write-Error "No certificate found with RequestID $RequestID on $CAFqdn"
            return
        }

        # BinaryCertificate in certutil CSV output is DER bytes encoded as base64
        $certRaw = $csvData.BinaryCertificate -replace '\s', ''
        $decoded = ConvertFrom-CertutilAsn1 -CertBase64 $certRaw
        $decoded | Add-ResultMetadata -Profile $Profile -CAServer $CAFqdn
    }
}