```powershell
<#
.SYNOPSIS
    Validates readiness for Windows 11 BitLocker with TPM + PIN and optionally applies the configuration.

.DESCRIPTION
    This script is intended as an operational helper for preparing a Windows 11 endpoint for
    BitLocker OS drive protection with TPM plus a startup PIN.

    It performs non-destructive checks by default:
      - Verifies admin context
      - Checks OS drive and BitLocker/TPM availability
      - Confirms UEFI boot mode when possible
      - Reports TPM status
      - Shows existing BitLocker protector and encryption state

    With -Configure, it will attempt to:
      - Add a TPM protector to the OS drive
      - Prompt for a startup PIN and add a TPM+PIN protector
      - Start BitLocker on the OS drive (used-space-only optional)

    The script is vendor-neutral and does not store or transmit secrets.
    It assumes recovery key escrow is handled by your organization’s normal process.

.NOTES
    Run from an elevated PowerShell session.
    Review your policy and recovery requirements before using -Configure.
    Test on non-production devices first.

.EXAMPLE
    .\Invoke-BitLockerTpmPin.ps1
    Runs readiness checks only.

.EXAMPLE
    .\Invoke-BitLockerTpmPin.ps1 -Configure -UsedSpaceOnly
    Applies TPM + PIN protection and starts BitLocker using used-space-only encryption.

.EXAMPLE
    .\Invoke-BitLockerTpmPin.ps1 -Configure -OsDriveLetter D:
    Uses a specified OS drive letter if needed for a managed image or unusual layout.
#>

[CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Medium')]
param(
    [Parameter()]
    [ValidatePattern('^[A-Z]:\\$')]
    [string]$OsDriveLetter = 'C:\',

    [Parameter()]
    [switch]$Configure,

    [Parameter()]
    [switch]$UsedSpaceOnly,

    [Parameter()]
    [switch]$SkipUefiCheck,

    [Parameter()]
    [switch]$SkipTpmCheck
)

function Test-IsAdministrator {
    $currentIdentity = [Security.Principal.WindowsIdentity]::GetCurrent()
    $principal = New-Object Security.Principal.WindowsPrincipal($currentIdentity)
    return $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
}

function Get-BootModeSummary {
    try {
        $firmwareType = (Get-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control' -Name 'PEFirmwareType' -ErrorAction Stop).PEFirmwareType
        switch ($firmwareType) {
            1 { return 'BIOS' }
            2 { return 'UEFI' }
            default { return "Unknown ($firmwareType)" }
        }
    }
    catch {
        return 'Unknown'
    }
}

function Get-TpmSummary {
    try {
        $tpm = Get-Tpm -ErrorAction Stop
        [pscustomobject]@{
            TpmPresent            = [bool]$tpm.TpmPresent
            TpmReady              = [bool]$tpm.TpmReady
            ManagedAuthLevel      = $tpm.ManagedAuthLevel
            OwnerAuthPresent      = [bool]$tpm.OwnerAuth
            AutoProvisioning      = $tpm.AutoProvisioning
            TpmEnabled            = [bool]$tpm.TpmEnabled
            TpmActivated          = [bool]$tpm.TpmActivated
        }
    }
    catch {
        [pscustomobject]@{
            TpmPresent       = $false
            TpmReady         = $false
            ManagedAuthLevel = $null
            OwnerAuthPresent = $false
            AutoProvisioning = $null
            TpmEnabled       = $false
            TpmActivated     = $false
        }
    }
}

function Get-OsDriveInfo {
    param([string]$Drive)

    $vol = Get-Volume -DriveLetter ($Drive.TrimEnd('\').TrimEnd(':')) -ErrorAction Stop
    $part = Get-Partition -DriveLetter $vol.DriveLetter -ErrorAction Stop

    [pscustomobject]@{
        DriveLetter = "$($vol.DriveLetter):"
        FileSystem  = $vol.FileSystem
        SizeGB      = [math]::Round($vol.Size / 1GB, 2)
        FreeGB      = [math]::Round($vol.SizeRemaining / 1GB, 2)
        Bootable    = [bool]$part.IsBoot
    }
}

function Show-CurrentState {
    param([string]$Drive)

    Write-Host '--- Readiness Check ---'
    Write-Host "Admin context: $([bool](Test-IsAdministrator))"
    Write-Host "Boot mode: $(Get-BootModeSummary)"

    $tpm = Get-TpmSummary
    Write-Host "TPM present: $($tpm.TpmPresent)"
    Write-Host "TPM ready: $($tpm.TpmReady)"
    Write-Host "TPM enabled: $($tpm.TpmEnabled)"
    Write-Host "TPM activated: $($tpm.TpmActivated)"

    try {
        $osInfo = Get-OsDriveInfo -Drive $Drive
        Write-Host "OS drive: $($osInfo.DriveLetter)"
        Write-Host "File system: $($osInfo.FileSystem)"
        Write-Host "Drive size (GB): $($osInfo.SizeGB)"
        Write-Host "Free space (GB): $($osInfo.FreeGB)"
    }
    catch {
        Write-Warning "Could not query drive information for $Drive. $_"
    }

    try {
        $status = Get-BitLockerVolume -MountPoint $Drive -ErrorAction Stop
        Write-Host "BitLocker protection status: $($status.ProtectionStatus)"
        Write-Host "Encryption percentage: $($status.EncryptionPercentage)"
        Write-Host "Volume status: $($status.VolumeStatus)"
        Write-Host "Key protectors:"
        $status.KeyProtector | ForEach-Object { Write-Host "  - $($_.KeyProtectorType) [$($_.KeyProtectorId)]" }
    }
    catch {
        Write-Warning "BitLocker state could not be retrieved. $_"
    }
}

function Ensure-Prechecks {
    param(
        [string]$Drive,
        [switch]$SkipUefi,
        [switch]$SkipTpm
    )

    if (-not (Test-IsAdministrator)) {
        throw 'This script must be run from an elevated PowerShell session.'
    }

    if (-not $SkipUefi) {
        $bootMode = Get-BootModeSummary
        if ($bootMode -ne 'UEFI') {
            throw "UEFI boot mode is required for this configuration. Current mode: $bootMode"
        }
    }

    if (-not $SkipTpm) {
        $tpm = Get-TpmSummary
        if (-not $tpm.TpmPresent) {
            throw 'TPM is not present or could not be queried.'
        }
        if (-not $tpm.TpmEnabled -or -not $tpm.TpmActivated) {
            throw 'TPM is present but not enabled and activated.'
        }
    }

    try {
        $osInfo = Get-OsDriveInfo -Drive $Drive
        if ($osInfo.FreeGB -lt 10) {
            Write-Warning 'Free space is low. BitLocker can still function, but ensure this matches your rollout standard.'
        }
    }
    catch {
        throw "Unable to validate the OS drive. $_"
    }
}

function Enable-TpmAndPin {
    param(
        [string]$Drive,
        [switch]$UseUsedSpaceOnly
    )

    $driveClean = $Drive.TrimEnd('\')

    if ($PSCmdlet.ShouldProcess($driveClean, 'Add TPM and TPM+PIN protectors and enable BitLocker')) {
        Write-Host "Adding TPM protector on $driveClean ..."
        manage-bde -protectors -add $driveClean -tpm | Out-Null

        Write-Host 'Adding TPM+PIN protector. You will be prompted to enter and confirm the PIN.'
        manage-bde -protectors -add $driveClean -tpmpin

        $args = @('-on', $driveClean)
        if ($UseUsedSpaceOnly) {
            $args += '-usedspaceonly'
        }

        Write-Host "Starting BitLocker on $driveClean ..."
        manage-bde @args | Out-Null
    }
}

try {
    Show-CurrentState -Drive $OsDriveLetter

    if (-not $Configure) {
        Write-Host ''
        Write-Host 'No changes were made. Re-run with -Configure to apply TPM + PIN protection.'
        return
    }

    Ensure-Prechecks -Drive $OsDriveLetter -SkipUefi:$SkipUefiCheck -SkipTpm:$SkipTpmCheck
    Enable-TpmAndPin -Drive $OsDriveLetter -UseUsedSpaceOnly:$UsedSpaceOnly

    Write-Host ''
    Write-Host 'Post-change validation:'
    manage-bde -status $OsDriveLetter
    manage-bde -protectors -get $OsDriveLetter

    Write-Host ''
    Write-Host 'Recommended next steps:'
    Write-Host '  1. Perform a controlled reboot.'
    Write-Host '  2. Confirm the pre-boot PIN prompt appears.'
    Write-Host '  3. Verify the correct PIN unlocks the system.'
    Write-Host '  4. Confirm recovery key escrow follows your organization process.'
}
catch {
    Write-Error $_
    exit 1
}
```