function Ensure-RealBitLockerKey { [CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact='Medium')] param( [Parameter(ParameterSetName='Single', Position=0)] [ValidatePattern('^[A-Z]:$')] [string]$MountPoint = $env:SystemDrive, [Parameter(ParameterSetName='All')] [switch]$AllDisks, [switch]$FullReencrypt, [switch]$PersistToRegistry, [Parameter(Mandatory=$true, ParameterSetName='Persist')] [int]$UDFNumber, [string]$RegistryBasePath = 'HKLM:\SOFTWARE\CentraStage' ) # Determine target drives if ($AllDisks) { $targets = Get-WmiObject -Query "SELECT DeviceID FROM Win32_LogicalDisk WHERE DriveType=3" | Select-Object -ExpandProperty DeviceID } else { $targets = @($MountPoint) } $results = @() foreach ($d in $targets) { if (-not $PSCmdlet.ShouldProcess("Volume $d","Ensure recovery key")) { continue } # Key regex $keyPattern = '^\d{6}(-\d{6}){7}$' $vol = Get-BitLockerVolume -MountPoint $d $curKey = $vol.KeyProtector | Where-Object KeyProtectorType -eq 'RecoveryPassword' | Select-Object -Last 1 -ExpandProperty RecoveryPassword if ($curKey -match $keyPattern) { $results += [PSCustomObject]@{ MountPoint = $d Action = 'None' RecoveryKey = $curKey AuditString = $null } continue } # Provision new key if ($FullReencrypt) { Disable-BitLocker -MountPoint $d -ErrorAction Stop while ((Get-BitLockerVolume -MountPoint $d).VolumeStatus -ne 'FullyDecrypted') { Start-Sleep 15 } Enable-BitLocker ` -MountPoint $d ` -UsedSpaceOnly ` -SkipHardwareTest ` -TpmProtector ` -RecoveryPasswordProtector ` -ErrorAction Stop $action = 'FullReencrypt' } else { $vol.KeyProtector | Where-Object KeyProtectorType -eq 'RecoveryPassword' | ForEach-Object { Remove-BitLockerKeyProtector -MountPoint $d -KeyProtectorId $_.KeyProtectorId } Add-BitLockerKeyProtector -MountPoint $d -RecoveryPasswordProtector -ErrorAction Stop $action = 'AddProtector' } # Grab the newly provisioned key $newKey = (Get-BitLockerVolume -MountPoint $d).KeyProtector | Where-Object KeyProtectorType -eq 'RecoveryPassword' | Select-Object -Last 1 -ExpandProperty RecoveryPassword $auditString = $null if ($PersistToRegistry) { # -- Replace PowerShell 7 ternary with if/else -- if ($env:usrAlert -match 'true') { $alert = 'Notice' } else { $alert = 'Status' } # -- Build TPM mask -- $t = Get-Tpm $mask = (if ($t.TpmPresent) { 1 } else { 0 }) + ` (if ($t.TpmReady) { 6 } else { 0 }) # Capture and discard the switch output switch ($mask) { 0 { $state = 'Absent'; break } 1 { $state = 'Disabled'; break } 3 { $state = 'Deactivated'; break } 7 { $state = 'Active'; break } Default { $state = 'Error' } } $null = $state # -- Replace PowerShell 7 “? :” for drives list -- if ($AllDisks) { $drives = $targets } else { $drives = ,$d } # Build disk-status string $diskStatus = '' foreach ($x in $drives) { $stat = (Get-BitLockerVolume -MountPoint $x).VolumeStatus switch ($stat) { 'FullyEncrypted' { $code = 'ENCPASS'; break } 'EncryptionInProgress' { $code = 'ENCPASS'; break } 'DecryptionInProgress' { $code = 'ENCFAIL'; break } 'EncryptionSuspended' { $code = 'ENCFAIL'; break } 'DecryptionSuspended' { $code = 'ENCFAIL'; break } 'EncryptingWipeInProgress' { $code = 'ENCFAIL'; break } Default { $code = 'ENCFAIL' } } $diskStatus += "/$x`$$code" } $diskStatus = $diskStatus.TrimStart('/') $auditString = "TPM: $mask | DISKS: $diskStatus | RECOVERY: $newKey" # Persist to registry/UDF New-ItemProperty ` -Path $RegistryBasePath ` -Name "Custom$UDFNumber" ` -Value $auditString ` -Force | Out-Null } $results += [PSCustomObject]@{ MountPoint = $d Action = $action RecoveryKey = $newKey AuditString = $auditString } } return $results }