#Requires -Version 5.1 <# JbTecWiz Support Centre -- generated fix script Fault : BitLocker asks for the recovery key at every boot Fix : Re-seal the key against the current boot configuration Source: https://jbtecwiz.com/support/win-sec-bitlocker-prompt Run as : Elevated PowerShell, once booted Expect : 25 minutes Risk : high Reversible : yes WHEN THIS IS THE RIGHT FIX You can get in with the key but it asks again every time. HOW TO UNDO IT The recovery key still unlocks the volume throughout. Re-adding the TPM protector can be repeated. This script walks the fix one step at a time and asks before each one. Steps with no command are things you do yourself -- it prints those and waits. Run with -DryRun to print without executing. -------------------------------------------------------------------- NO WARRANTY - USE AT YOUR OWN RISK This script is provided by JbTecWiz as-is and with no warranty of any kind, express or implied. You run it entirely at your own risk. JbTecWiz accepts no liability for any loss or damage arising from its use, including but not limited to data loss, downtime, or configuration changes that turn out to be wrong for your system. You are responsible for reading this script before running it, for satisfying yourself that it suits the machine in front of you, and for having a working backup first. Some steps cannot be undone. -------------------------------------------------------------------- #> [CmdletBinding()] param( # Print every step and command without running anything. [switch]$DryRun, # Do not ask before each step. Read the script first if you use this. [switch]$Unattended ) $ErrorActionPreference = 'Stop' $script:Failed = 0 function Write-Rule { param([string]$Text) Write-Host '' Write-Host ('-' * 70) -ForegroundColor DarkGray if ($Text) { Write-Host $Text -ForegroundColor Cyan } } function Show-Prose { param([string]$Text, [string]$Colour = "Gray") if (-not $Text) { return } $words = $Text -split "\s+"; $line = " " foreach ($w in $words) { if (($line.Length + $w.Length) -gt 74) { Write-Host $line -ForegroundColor $Colour; $line = " " } $line += "$w " } if ($line.Trim()) { Write-Host $line -ForegroundColor $Colour } } function Invoke-Step { param( [int]$Number, [string]$Do, [string]$Why, [scriptblock]$Command, [switch]$Manual, [string]$Shell = "powershell" ) Write-Rule " Step $Number of 5" Show-Prose $Do "White" if ($Why) { Write-Host ""; Show-Prose $Why "DarkGray" } if ($Manual) { Write-Host '' Write-Host ' -> Do this yourself, then press Enter to carry on.' -ForegroundColor Yellow if (-not $Unattended -and -not $DryRun) { [void](Read-Host) } return } Write-Host '' foreach ($l in ($Command.ToString().Trim() -split "`n")) { Write-Host (" " + $l.Trim()) -ForegroundColor Green } Write-Host '' if ($DryRun) { Write-Host " (dry run -- not executed)" -ForegroundColor DarkGray; return } if (-not $Unattended) { $a = Read-Host " Run this step? [Y]es / [S]kip / [Q]uit" if ($a -match "^[Qq]") { Write-Host " Stopped at your request."; exit 0 } if ($a -match "^[Ss]") { Write-Host " Skipped." -ForegroundColor DarkGray; return } } try { & $Command } catch { $script:Failed++ Write-Host (" Step $Number failed: " + $_.Exception.Message) -ForegroundColor Red Show-Prose "The rest of the fix may depend on this. Read the write-up before carrying on." "Red" if (-not $Unattended) { $c = Read-Host " Carry on anyway? [y/N]" if ($c -notmatch "^[Yy]") { exit 1 } } } } Write-Rule Write-Host ' BitLocker asks for the recovery key at every boot' -ForegroundColor White Write-Host ' Re-seal the key against the current boot configuration' -ForegroundColor Cyan Write-Host '' Write-Host ' Risk: high Reversible 25 minutes' Write-Host '' Show-Prose 'No warranty. Use at your own risk - JbTecWiz accepts no liability. Read it before you run it, and have a backup.' 'DarkYellow' Write-Rule if (-not $Unattended -and -not $DryRun) { $go = Read-Host ' Ready? [y/N]' if ($go -notmatch "^[Yy]") { Write-Host " Nothing was changed."; exit 0 } } Invoke-Step -Number 1 -Do 'Record the key somewhere safe first, and confirm it is escrowed. Everything below can be undone with the key and cannot be undone without it.' -Command { manage-bde -protectors -get C: } Invoke-Step -Number 2 -Do 'Check what BitLocker thinks is wrong.' -Command { Get-BitLockerVolume -MountPoint C: | Format-List MountPoint,VolumeStatus,ProtectionStatus,KeyProtector Get-WinEvent -LogName Microsoft-Windows-BitLocker/BitLocker\ Management -MaxEvents 20 -ErrorAction SilentlyContinue | Format-Table TimeCreated,Id,Message -Wrap } Invoke-Step -Number 3 -Do 'Suspend protection, apply whatever firmware or boot change is outstanding, then resume -- this is the supported way to make a change without triggering recovery.' -Why 'RebootCount 2 suspends for two restarts, which is enough for a firmware update to complete, and then protection resumes automatically. Suspending indefinitely and forgetting is how machines end up unencrypted for months.' -Command { Suspend-BitLocker -MountPoint C: -RebootCount 2 } Invoke-Step -Number 4 -Do 'If the TPM protector is missing or stale, remove and re-add it so the key is sealed against the current measurements.' -Command { manage-bde -protectors -delete C: -type tpm manage-bde -protectors -add C: -tpm } Invoke-Step -Number 5 -Do 'Resume protection and restart twice to confirm.' -Command { Resume-BitLocker -MountPoint C: } Write-Rule " Confirm it worked" Show-Prose 'Two consecutive restarts reach the sign-in screen with no recovery prompt.' 'White' Write-Host '' if (-not $DryRun) { Get-BitLockerVolume -MountPoint C: | Format-List ProtectionStatus,VolumeStatus,KeyProtector } Write-Rule if ($script:Failed -gt 0) { Write-Host (" Finished with " + $script:Failed + " failed step(s).") -ForegroundColor Yellow Show-Prose 'Read the full write-up at https://jbtecwiz.com/support/win-sec-bitlocker-prompt' 'Yellow' } else { Write-Host ' Finished.' -ForegroundColor Green } Write-Host '' Show-Prose 'To undo: The recovery key still unlocks the volume throughout. Re-adding the TPM protector can be repeated.' 'DarkGray' Write-Rule