HomeNewsletterCommunityToolsArchiveBlogToday's NewsAboutServicesQuick Links Subscribe free
← Back to Blog

Your BitLocker Escrow Report Says 100%. When Did Anyone Last Prove One of Those Keys Still Matches the Drive?

IA
Imran Awan
23 July 2026

Run a BitLocker escrow audit across a fleet and it's easy to feel good about a 100% GREEN result. But GREEN in that kind of audit only means one thing: a recovery key record exists somewhere in Entra ID or Active Directory for that device. It says nothing about whether that specific record is the key that would actually unlock the drive today. Those are two different claims, and the gap between them is exactly where a "compliant" fleet can still lose data on the one day it matters.

This post is a direct follow-up to the BitLocker recovery key escrow audit already on this site. That audit answers "does a key exist?" This one answers a sharper question: "is the key that exists actually the one protecting this drive right now?" — and gives you a script to check.

The problem — existence isn't currency

A BitLocker recovery key isn't a single, permanent secret tied to a device forever. It's tied to a specific key protector — one instance of a protector object, generated at a specific point in time, identified by its own GUID (KeyProtectorId). When that protector gets replaced — by a re-image, a protector rotation, a TPM reset, or BitLocker being suspended and re-enabled — the volume gets a new key protector with a new ID. The old escrowed record doesn't get deleted. It just sits in Entra ID or AD, permanently, describing a protector that no longer exists on any drive.

Run the escrow audit against that device and it still reports GREEN — a key record exists, dated, timestamped, present. It's just not the key you'd actually need if that drive locked tomorrow.

Why this matters more than a missing key: a device with no escrowed key at all is at least an obvious, visible gap — it shows RED, someone investigates. A device with a stale escrowed key looks identical to a healthy one in every dashboard that only checks for existence. It's the failure mode that hides.

Why it happens — key protectors rotate, escrow records don't self-clean

Several ordinary, well-documented events on a device mint a new local key protector without anyone doing anything wrong:

None of these events reach into Entra ID or Active Directory and remove the old record. Recovery key escrow is additive by design — Microsoft's own guidance is that you should back up a new protector when one is created, not that old ones get pruned. That's the right default for not losing history, but it also means an escrow store accumulates dead records over a device's lifetime, and nothing forces a re-escrow after most of the events above unless your process explicitly does it.

Gotcha — this pairs badly with re-imaging workflows that don't include a re-escrow step. If your Autopilot or imaging process wipes and re-provisions a device without an explicit step to back up the new key protector afterward, every re-imaged device in your fleet is walking around with a stale escrow record from its previous life, invisible to an existence-only audit.

How to verify — compare the local protector ID against what's actually escrowed

The only way to know if an escrowed key is current is to compare it against what the device itself says is protecting the drive right now. Locally, Get-BitLockerVolume returns a KeyProtector array, and each entry in that array has its own KeyProtectorId:

Windows PowerShell — run locally, as Administrator
$BLV = Get-BitLockerVolume -MountPoint "C:" $BLV.KeyProtector | Select-Object KeyProtectorType, KeyProtectorId # KeyProtectorType KeyProtectorId # ---------------- -------------- # Tpm {a1b2c3d4-....} # RecoveryPassword {e5f6a7b8-....}

On the cloud side, Microsoft Graph's bitlockerRecoveryKey resource stores each escrowed key with its own id, plus the deviceId it was backed up from and a createdDateTime. Listing the escrowed keys for a device and comparing their IDs against the live local KeyProtectorId for the RecoveryPassword protector tells you, directly, whether the record on file is current.

Being honest about what's actually documented here: Microsoft's own reference pages don't explicitly spell out that the Graph bitlockerRecoveryKey.id is guaranteed to equal the local KeyProtectorId GUID byte-for-byte in every case. In practice, backing up a protector with BackupToAAD-BitLockerKeyProtector -KeyProtectorId is how the ID gets there in the first place, so a match is the expected outcome — but the script below treats a non-match as "needs manual review," not an automatic hard failure, precisely because that exact guarantee isn't spelled out in the docs.

The fix — re-escrow on drift, and check re-imaging workflows specifically

When drift is found on a device
  1. Confirm you're looking at the RecoveryPassword protector specifically — a volume can have multiple protector types (Tpm, RecoveryPassword, Password), and only the RecoveryPassword one is what gets escrowed for recovery purposes.
  2. Re-escrow the current protector immediately: BackupToAAD-BitLockerKeyProtector -MountPoint "C:" -KeyProtectorId $BLV.KeyProtector[1].KeyProtectorId (for Entra ID), or Backup-BitLockerKeyProtector for on-prem AD DS.
  3. If this is a re-imaging pipeline issue rather than a one-off, add the backup command as a mandatory step immediately after Enable-BitLocker in the provisioning script or task sequence — don't rely on Intune's encryption policy alone to catch devices that were encrypted outside its assignment.
  4. Old, stale records don't need to be deleted to fix this — a device having an old dead record alongside a current one is harmless. The risk is only in not having a current one.
The good news: if your Intune encryption profile already has "Save BitLocker recovery information to Microsoft Entra ID" enabled and correctly assigned, new encryptions and most protector rotations initiated through normal Windows behaviour get escrowed automatically going forward. This is almost always a problem with historical drift — devices encrypted, re-imaged, or rotated before or outside that policy's reach — not with the policy itself.

Proof it worked — a currency check, not a claim of "we tested every key"

Be precise about what this actually proves. Confirming that a local KeyProtectorId matches an escrowed record's ID proves the right record is on file. It does not prove that record would successfully decrypt the volume in a real recovery scenario — that would require an actual offline unlock test against a genuinely locked volume, which isn't something you can safely automate across a live fleet. Treat a real unlock test as a lab-only exercise on a spare device, not something this script claims to do at scale. What the script below does is the honest, safe, at-scale version: it tells you whether the record on file is even the current one, which is the far more common failure mode.

Download the script — GitHub

Test-BitLockerRecoveryKeyCurrency.ps1 is free and open source. It's a genuinely read-only check — no writes to BitLocker, Intune, or Entra ID.

Test-BitLockerRecoveryKeyCurrency.ps1 View full repo →
Example output below is illustrative, not a live-device capture. It matches the script's real structure and message wording, with fictional key IDs, so you can see what a run looks like before testing it yourself. This example shows the STALE case specifically, since that's the failure mode existence-only audits miss.
Test-BitLockerRecoveryKeyCurrency.ps1 — example output (illustrative)
.\Test-BitLockerRecoveryKeyCurrency.ps1 [1] Reading local BitLocker key protectors for C:... Local RecoveryPassword KeyProtectorId: a9f3c7e1-4b82-4d10-9e55-7c21f0a83b6d [2] Resolving this device's Microsoft Entra device ID... Entra device ID: 3d9a7c11-2b44-4e6a-8f10-1a9d5e6c2b77 [3] Connecting to Microsoft Graph... [4] Retrieving escrowed BitLocker recovery keys for this device from Entra ID... ============================================================ BITLOCKER RECOVERY KEY CURRENCY CHECK - C: ============================================================ Found 1 escrowed record(s) for this device. STALE - escrowed record(s) exist, but none match the current local KeyProtectorId. Local KeyProtectorId : a9f3c7e1-4b82-4d10-9e55-7c21f0a83b6d Escrowed record : 6e1d2f88-903a-4c5e-8b7f-2a4c9d1e6f30 (created 2025-02-11T09:30:04Z) This device's escrowed key record is out of date. Re-escrow the current protector: BackupToAAD-BitLockerKeyProtector -MountPoint "C:" -KeyProtectorId "a9f3c7e1-4b82-4d10-9e55-7c21f0a83b6d" Note: this confirms the record on file is not current. It does not, by itself, prove the record would fail to decrypt the volume - Microsoft's docs do not explicitly guarantee the ID mapping in every case. Treat STALE as 'needs manual review and re-escrow', not an automatic hard failure.
Note on required permissions and access: this script needs local access to run Get-BitLockerVolume on the device itself, plus Graph read access (BitLockerKey.ReadBasic.All) to list that device's escrowed records — it can't be run purely centrally from a Graph-only context, because the "what's actually protecting this drive right now" half of the comparison only exists on the device.

References

Share this post
LinkedIn X / Twitter Reddit Bluesky

More from EndpointWeekly

Security
How Many of Your BitLocker Devices Actually Have a Recovery Key Escrowed Anywhere?
The original audit — proves a key exists. This post proves it's the right one.
Security
Windows 11 Secure Boot and BitLocker — June 2026
What changed and what IT admins need to check before the next update wave.
Security
LAPS Rotation Compliance Audit
The same existence-vs-currency problem, applied to local admin passwords instead of recovery keys.