```powershell
<#
.SYNOPSIS
    Checks readiness for Windows 10 BitLocker TPM + PIN protection and optionally enables BitLocker on the operating system drive.

.DESCRIPTION
    This script performs operational checks before rollout:
    - Verifies TPM status
    - Checks BitLocker volume status
    - Confirms the operating system drive
    - Optionally refreshes Group Policy
    - Optionally enables BitLocker with TPM + PIN on the OS volume
    - Validates protector state after enablement

    The script is designed to be safe by default:
    - No encryption is enabled unless -EnableBitLocker is specified
    - No changes are made to firmware or TPM ownership
    - No credentials or secrets are required
    - The script exits with clear guidance if prerequisites are not met

.NOTES
    Run in an elevated PowerShell session.
    Intended for Windows 10 environments with TPM-backed BitLocker management.
#>

[CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'High')]
param(
    [ValidatePattern('^[A-Z]$')]
    [string]$OSDrive = 'C',

    [switch]$RefreshPolicy,

    [switch]$EnableBitLocker,

    [switch]$WhatIfMode
)

Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'

function Write-Section {
    param([string]$Text)
    Write-Host "`n=== $Text ===" -ForegroundColor Cyan
}

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

function Get-DriveRoot {
    param([string]$Letter)
    return "{0}:" -f $Letter.ToUpperInvariant()
}

function Get-TpmStateSafe {
    try {
        return Get-Tpm
    }
    catch {
        throw "Unable to query TPM state. Ensure the TPM module is available and the device supports TPM. Details: $($_.Exception.Message)"
    }
}

function Get-BitLockerStatusSafe {
    param([string]$DriveRoot)
    try {
        return Get-BitLockerVolume -MountPoint $DriveRoot
    }
    catch {
        throw "Unable to query BitLocker volume status for $DriveRoot. Details: $($_.Exception.Message)"
    }
}

function Test-Prerequisites {
    param(
        $Tpm,
        $BitLockerVolume,
        [string]$DriveRoot
    )

    $issues = New-Object System.Collections.Generic.List[string]

    if (-not $Tpm.TpmPresent)  { $issues.Add('TPM is not present.') }
    if (-not $Tpm.TpmEnabled)  { $issues.Add('TPM is present but not enabled.') }
    if (-not $Tpm.TpmActivated){ $issues.Add('TPM is present but not activated.') }
    if (-not $Tpm.TpmReady)    { $issues.Add('TPM is not ready.') }

    if ($BitLockerVolume.VolumeStatus -eq 'Unknown') {
        $issues.Add("BitLocker volume status for $DriveRoot could not be determined.")
    }

    return $issues
}

function Show-StatusSummary {
    param(
        $Tpm,
        $BitLockerVolume,
        [string]$DriveRoot
    )

    Write-Section 'TPM Status'
    [pscustomobject]@{
        TpmPresent   = $Tpm.TpmPresent
        TpmEnabled   = $Tpm.TpmEnabled
        TpmActivated = $Tpm.TpmActivated
        TpmReady     = $Tpm.TpmReady
        TpmOwned     = $Tpm.TpmOwned
    } | Format-List | Out-String | Write-Host

    Write-Section 'BitLocker Status'
    [pscustomobject]@{
        DriveRoot        = $DriveRoot
        VolumeStatus     = $BitLockerVolume.VolumeStatus
        EncryptionMethod = $BitLockerVolume.EncryptionMethod
        ProtectionStatus = $BitLockerVolume.ProtectionStatus
        LockStatus       = $BitLockerVolume.LockStatus
    } | Format-List | Out-String | Write-Host
}

function Invoke-PolicyRefresh {
    if ($PSCmdlet.ShouldProcess('Local computer', 'Refresh Group Policy')) {
        Write-Section 'Refreshing policy'
        gpupdate /force | Out-Host
    }
}

function Get-StartupProtectorMatch {
    param($BitLockerVolume)

    $protectors = @()
    try {
        $protectors = Get-BitLockerVolume -MountPoint $BitLockerVolume.MountPoint | Select-Object -ExpandProperty KeyProtector
    }
    catch {
        return $null
    }

    return $protectors
}

function Enable-OsDriveBitLockerWithTpmPin {
    param(
        [string]$DriveRoot
    )

    Write-Section 'Enable BitLocker with TPM + PIN'
    Write-Host "This step will attempt to enable BitLocker on $DriveRoot using TPM + PIN protection." -ForegroundColor Yellow
    Write-Host 'You may be prompted to choose or confirm a startup PIN during the BitLocker workflow.' -ForegroundColor Yellow

    if (-not $PSCmdlet.ShouldProcess($DriveRoot, 'Enable BitLocker with TPM + PIN')) {
        return
    }

    try {
        # Preferred on supported systems: use the built-in enablement flow.
        # This command may prompt interactively depending on policy and OS version.
        manage-bde -on $DriveRoot -tpmandpin | Out-Host
    }
    catch {
        throw "Failed to start BitLocker enablement for $DriveRoot. Details: $($_.Exception.Message)"
    }
}

function Show-ProtectorDetails {
    param([string]$DriveRoot)

    Write-Section 'BitLocker protectors'
    try {
        manage-bde -protectors -get $DriveRoot | Out-Host
    }
    catch {
        Write-Warning "Could not retrieve protectors with manage-bde. Details: $($_.Exception.Message)"
    }
}

function Test-RebootReadiness {
    param([string]$DriveRoot)

    $vol = Get-BitLockerStatusSafe -DriveRoot $DriveRoot
    if ($vol.ProtectionStatus -ne 'On' -and $vol.VolumeStatus -notin @('EncryptionInProgress','FullyEncrypted')) {
        Write-Warning "BitLocker does not appear fully enabled yet on $DriveRoot. Verify encryption progress and policy state before reboot testing."
    }
}

# --- Main ---

if ($WhatIfMode) {
    $WhatIfPreference = $true
}

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

$driveRoot = Get-DriveRoot -Letter $OSDrive

Write-Section 'Collecting baseline state'
$tpm = Get-TpmStateSafe
$bitlockerVolume = Get-BitLockerStatusSafe -DriveRoot $driveRoot
Show-StatusSummary -Tpm $tpm -BitLockerVolume $bitlockerVolume -DriveRoot $driveRoot

$issues = Test-Prerequisites -Tpm $tpm -BitLockerVolume $bitlockerVolume -DriveRoot $driveRoot
if ($issues.Count -gt 0) {
    Write-Section 'Prerequisite issues'
    $issues | ForEach-Object { Write-Warning $_ }
    Write-Host "`nResolve the items above before enabling TPM + PIN protection." -ForegroundColor Yellow
    if (-not $EnableBitLocker) {
        return
    }
}

if ($RefreshPolicy) {
    Invoke-PolicyRefresh
}

if ($EnableBitLocker) {
    if ($issues.Count -gt 0) {
        throw 'Prerequisites are not met. Refusing to enable BitLocker until TPM readiness and volume state are corrected.'
    }

    Enable-OsDriveBitLockerWithTpmPin -DriveRoot $driveRoot
    Start-Sleep -Seconds 2
    Show-ProtectorDetails -DriveRoot $driveRoot
    Test-RebootReadiness -DriveRoot $driveRoot
}
else {
    Write-Host "`nNo enablement requested. Use -EnableBitLocker to start TPM + PIN protection after validating prerequisites." -ForegroundColor Green
    Show-ProtectorDetails -DriveRoot $driveRoot
}

Write-Section 'Operational validation checklist'
Write-Host '1. Confirm TPM is present, enabled, activated, and ready.'
Write-Host '2. Confirm policy allows or requires TPM + PIN startup authentication.'
Write-Host '3. Confirm a recovery path exists and is escrowed according to your process.'
Write-Host '4. Reboot the device in a controlled window and verify the pre-boot PIN prompt appears.'
Write-Host '5. Confirm the machine boots normally only after the correct PIN is entered.'

```