Public/Get-PWSHPUKMGT-Puk.ps1

<#
.SYNOPSIS
    Gets the PUK and linked crypto device serial number for a user.
.DESCRIPTION
    Resolves the given identity in Active Directory, looks up its PWSHPUKMGT record in the
    configured hosting backend (flat file or Active Directory), and returns the stored PUK
    alongside the linked crypto device serial number. The PUK is returned as a SecureString
    by default; pass -AsPlainText to receive it as a plain string instead. Because -AsPlainText
    puts the PUK in clear text in the pipeline (and in any transcript or log that captures pipeline
    output), it should only be used when that risk is understood and accepted by the caller.
.PARAMETER Identity
    A SamAccountName, UserPrincipalName, or DistinguishedName identifying the user. Accepts
    pipeline input, including AD user objects.
.PARAMETER AsPlainText
    Return the PUK as a plain string instead of a SecureString.
.PARAMETER Server
    The domain controller to run the underlying LDAP requests against. Defaults to the value
    configured in hosting.activeDirectory.server, or, if that is not set either, to the primary
    domain controller (PDC emulator) of the current domain.
.EXAMPLE
    Get-PWSHPUKMGT-Puk -Identity 'alice'
.EXAMPLE
    Get-PWSHPUKMGT-Puk -Identity 'alice' -AsPlainText
.OUTPUTS
    PSCustomObject
    Has Identity, DistinguishedName, SerialNumber, and Puk properties. Puk is a SecureString
    unless -AsPlainText is specified.
#>

function Get-PWSHPUKMGT-Puk {
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingConvertToSecureStringWithPlainText', '', Justification = 'The plaintext PUK read from storage is intentionally converted to a SecureString at this API boundary (default output); -AsPlainText is an explicit, documented opt-out.')]
    [CmdletBinding()]
    [OutputType([psobject])]
    param(
        [Parameter(Mandatory, Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Alias('SamAccountName', 'UserPrincipalName', 'DistinguishedName')]
        [string]$Identity,

        [switch]$AsPlainText,

        [string]$Server
    )

    begin {
        $config = Get-PukModuleConfig
        $certificate = Test-PukCertificate -Thumbprint $config.certificate.thumbprint -StoreLocation $config.certificate.storeLocation -RequiredEkuOids $config.certificate.requiredEkuOids
        $effectiveServer = Resolve-PukServer -Server $Server -Config $config
    }

    process {
        $distinguishedName = Resolve-PukIdentity -Identity $Identity -Server $effectiveServer
        $record = Get-PukRecord -Config $config -Certificate $certificate -DistinguishedName $distinguishedName -Server $effectiveServer

        if (-not $record) {
            Write-Error "No PWSHPUKMGT record found for '$Identity'."
            return
        }

        $puk = if ($AsPlainText) {
            $record.Puk
        }
        else {
            ConvertTo-SecureString -String $record.Puk -AsPlainText -Force
        }

        [PSCustomObject]@{
            PSTypeName        = 'PWSHPUKMGT.PukResult'
            Identity          = $Identity
            DistinguishedName = $record.DistinguishedName
            SerialNumber      = $record.SerialNumber
            Puk               = $puk
        }
    }
}