How to Export BitLocker Recovery Keys from Active Directory With PowerShell
Use the ActiveDirectory PowerShell module to export BitLocker recovery keys from Active Directory into a CSV, then validate the 48-digit passwords and keep the file secure.
- Difficulty
- Intermediate
- Time required
- About 15 minutes
- Steps
- 7
- Platform
- Active Directory

Table of contents
Quick Answer
Go to the stepsTo export BitLocker recovery keys from Active Directory, import the ActiveDirectory PowerShell module, then read the msFVE-RecoveryInformation objects stored under each computer account and pipe the results to Export-Csv. The keys only appear if Group Policy backed them up to AD DS when BitLocker was turned on, and reading the recovery password needs Domain Admin rights or delegated access.
- Install RSAT and import the ActiveDirectory module.
- Confirm recovery keys exist in AD with a quick query.
- Run the export script to write every key to CSV.
- Validate the recovery password format and row count.
- Store the CSV securely and restrict access.
Get-ADObject -LDAPFilter '(objectClass=msFVE-RecoveryInformation)' -SearchBase (Get-ADDomain).DistinguishedName -Properties 'msFVE-RecoveryPassword'Expected result: A CSV that lists each computer, its 48-digit recovery password, the recovery key ID, and the date the key was created.
Key takeaways
- How to use the ActiveDirectory PowerShell module to export BitLocker recovery keys from Active Directory Domain Services into a structured CSV report.
- Recovery keys are the last line of access to encrypted drives. A fast, scripted export gives your help desk a searchable record and shows which devices never escrowed a key at all.
- With the ActiveDirectory module and the right permissions, one script pulls every escrowed BitLocker recovery key into a CSV you can search and audit.
Introduction
BitLocker recovery keys for domain-joined Windows devices can live in Active Directory, stored as msFVE-RecoveryInformation objects under each computer account. When a user is locked out of an encrypted drive, that 48-digit recovery password is often the only way back in. Clicking through Active Directory Users and Computers one machine at a time doesn't scale, so this guide uses the ActiveDirectory PowerShell module to pull every recovery key into a single CSV, complete with computer name, key ID, and creation date. You'll confirm the keys are actually escrowed, build a reusable export script, validate the output, and lock down the file, since a CSV of recovery passwords is as sensitive as data gets.
Who this is for: Windows and Active Directory admins who manage BitLocker on domain-joined devices and need to retrieve or audit recovery keys at scale.
Before you start
- Access
- A domain-joined admin workstation or a domain controller, with the ActiveDirectory PowerShell module and network access to a domain controller.
- Required roles
- Domain Admins, or an account with delegated Read and Control Access on the msFVE-RecoveryPassword attribute
- Environment
- Active Directory Domain Services with the BitLocker AD DS backup Group Policy already configured, and computers that had BitLocker enabled after that policy applied.
- Vendor
- Microsoft
- Tested environment
- ActiveDirectory PowerShell module (RSAT), verified against Microsoft Learn BitLocker recovery documentation, July 2026.
- Administrator permissions required
Commands use the ActiveDirectory module from RSAT, verified against Microsoft's current BitLocker and Active Directory documentation.
About 15 minutes, plus run time that scales with the number of computer objects.
Critical: Treat the export like the keys themselves
A CSV of BitLocker recovery passwords can unlock every listed drive. Write it to a protected, access-controlled location, remove it when you're done, and never email it or leave it on a share.
Note: Reading recovery passwords needs the right rights
By default only Domain Admins can read the msFVE-RecoveryPassword attribute. If you delegate this to a help desk group, grant read access to that attribute only, not full control of the objects.
1Install the ActiveDirectory module and confirm domain access
Get the ActiveDirectory PowerShell module in place and confirm you can reach the domain.
The export relies on the ActiveDirectory module, which ships with the Remote Server Administration Tools (RSAT).
On Windows 10 or 11, add the module:
Add-WindowsCapability -Online -Name Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0On a domain controller or a server with the AD DS role, the module is already present. Import it and confirm you can reach the domain:
Import-Module ActiveDirectory
Get-ADDomainIf you run PowerShell 7, load the module in compatibility mode, since the ActiveDirectory module targets Windows PowerShell:
Import-Module ActiveDirectory -UseWindowsPowerShellImport-Module ActiveDirectory; Get-ADDomainExpected result: Get-ADDomain returns your domain details, such as DNSRoot and DomainMode, with no errors.
Note
The -UseWindowsPowerShell switch is the supported way to use the ActiveDirectory module from PowerShell 7. It loads the module through a background Windows PowerShell session.
2Confirm the recovery keys are actually in Active Directory
Check that BitLocker escrowed keys before you build a full export.
Before scripting anything, confirm the keys exist. BitLocker only writes recovery information to AD DS if Group Policy told it to, and only for volumes encrypted after that policy applied.
Run a quick domain-wide query for recovery objects:
Get-ADObject -LDAPFilter '(objectClass=msFVE-RecoveryInformation)' -SearchBase (Get-ADDomain).DistinguishedName -Properties 'msFVE-RecoveryPassword' |
Select-Object -First 5 Name, 'msFVE-RecoveryPassword'Each result is a recovery object stored under a computer account. The Name holds a timestamp and the recovery key ID in braces, and msFVE-RecoveryPassword holds the 48-digit key.
Get-ADObject -LDAPFilter '(objectClass=msFVE-RecoveryInformation)' -SearchBase (Get-ADDomain).DistinguishedName -Properties 'msFVE-RecoveryPassword' | Select-Object -First 5 Name, 'msFVE-RecoveryPassword'Expected result: You see one or more msFVE-RecoveryInformation entries with a populated 48-digit msFVE-RecoveryPassword. An empty result means keys aren't being escrowed to AD.
Note
If nothing returns, the backup Group Policy is missing or was applied after those drives were encrypted. See the troubleshooting section.
3Build the export script
Create a reusable script that walks computer accounts and writes every recovery key to CSV.
Save the following as Export-BitLockerKeys.ps1. It reads each computer account, pulls the recovery objects stored beneath it, and writes a flat CSV.
param(
[string]$SearchBase,
[string]$OutputPath = 'C:\Reports\BitLockerKeys.csv'
)
Import-Module ActiveDirectory
# Make sure the output folder exists
$dir = Split-Path $OutputPath -Parent
if (-not (Test-Path $dir)) { New-Item -ItemType Directory -Path $dir -Force | Out-Null }
# Collect computer accounts, domain-wide or from one OU
$adParams = @{ Filter = '*'; Properties = 'OperatingSystem', 'LastLogonDate' }
if ($SearchBase) { $adParams['SearchBase'] = $SearchBase }
$computers = Get-ADComputer @adParams
$results = foreach ($computer in $computers) {
# Recovery keys are child objects of the computer account
$keyParams = @{
LDAPFilter = '(objectClass=msFVE-RecoveryInformation)'
SearchBase = $computer.DistinguishedName
Properties = 'msFVE-RecoveryPassword', 'whenCreated'
}
foreach ($key in (Get-ADObject @keyParams)) {
[PSCustomObject]@{
ComputerName = $computer.Name
OperatingSystem = $computer.OperatingSystem
RecoveryKeyId = $key.Name.Split('{')[-1].TrimEnd('}')
RecoveryPassword = $key.'msFVE-RecoveryPassword'
KeyCreated = $key.whenCreated
LastLogon = $computer.LastLogonDate
}
}
}
$results | Export-Csv -Path $OutputPath -NoTypeInformation -Encoding UTF8
Write-Host "Exported $($results.Count) recovery keys to $OutputPath"The script takes two optional parameters: -SearchBase to limit the search to one OU, and -OutputPath to set the CSV location.
Expected result: A saved Export-BitLockerKeys.ps1 file that runs without syntax errors and defines the -SearchBase and -OutputPath parameters.
Note
The recovery key ID comes from the object name, which ends with the GUID in braces. You can also read the raw msFVE-RecoveryGuid attribute if you prefer the binary value.
4Allow the script to run
Let PowerShell run your local script without loosening security more than needed.
Check the current execution policy:
Get-ExecutionPolicyIf it returns Restricted, allow local scripts for your user with RemoteSigned:
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUserOr bypass the policy for this one run without changing the machine setting:
powershell.exe -ExecutionPolicy Bypass -File 'C:\Reports\Export-BitLockerKeys.ps1'Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUserExpected result: Get-ExecutionPolicy reports RemoteSigned for your scope, or the script runs under a one-time Bypass.
Note
Keep away from Unrestricted on production systems. RemoteSigned runs local scripts while still blocking unsigned scripts downloaded from the internet.
5Run the export
Produce the CSV, either for the whole domain or a single OU.
Run the script from wherever you saved it. For the whole domain, set a timestamped output path:
.\Export-BitLockerKeys.ps1 -OutputPath "C:\Reports\BitLockerKeys_$(Get-Date -Format 'yyyyMMdd_HHmmss').csv"To scope the export to one organizational unit, pass its distinguished name. Find it first:
Get-ADOrganizationalUnit -Filter "Name -like '*Workstations*'" | Select-Object Name, DistinguishedNameThen run against that OU:
.\Export-BitLockerKeys.ps1 -SearchBase 'OU=Workstations,DC=example,DC=com' -OutputPath 'C:\Reports\BitLocker_Workstations.csv'Large domains take longer, since the script checks every computer account for child recovery objects.
Expected result: The script writes a CSV to your Reports folder and prints how many recovery keys it exported.
Note
Scope by OU whenever you can. It's faster and keeps each export limited to the devices you actually need.
6Validate the exported keys
Confirm the CSV is complete and the recovery passwords are well formed.
Load the CSV and check the basics: how many keys, and how many unique computers.
$data = Import-Csv 'C:\Reports\BitLockerKeys.csv'
$data.Count
($data | Select-Object ComputerName -Unique).CountA valid recovery password is 48 digits in eight groups of six. Flag any row that doesn't match:
$pattern = '^\d{6}-\d{6}-\d{6}-\d{6}-\d{6}-\d{6}-\d{6}-\d{6}$'
$data | Where-Object { $_.RecoveryPassword -notmatch $pattern } |
Select-Object ComputerName, RecoveryPasswordFinally, spot-check one device against Active Directory Users and Computers: enable View > Advanced Features, open the computer object, and compare the BitLocker Recovery tab to your CSV.
Expected result: The row count matches expectations, every recovery password fits the 48-digit pattern, and a spot-checked device matches the BitLocker Recovery tab.
Note
Computers with more than one row usually have multiple encrypted volumes or a rotated key. That's expected, not a duplicate.
7Secure the output and schedule recurring exports
Protect the CSV and, if you need ongoing reporting, automate it safely.
The export is a list of live recovery passwords, so handle it accordingly. Move it to a restricted location, tighten NTFS permissions to the specific admins who need it, and delete old copies once they're no longer needed.
If you need a regular report, schedule the script on a domain controller to run as SYSTEM, or on another host under a service account with delegated read access:
$action = New-ScheduledTaskAction -Execute 'powershell.exe' -Argument '-ExecutionPolicy Bypass -File "C:\Scripts\Export-BitLockerKeys.ps1"'
$trigger = New-ScheduledTaskTrigger -Weekly -DaysOfWeek Monday -At '02:00'
$principal = New-ScheduledTaskPrincipal -UserId 'SYSTEM' -LogonType ServiceAccount -RunLevel Highest
Register-ScheduledTask -TaskName 'BitLocker Key Export' -Action $action -Trigger $trigger -Principal $principalStore scheduled output on an access-controlled, ideally encrypted, volume, and prune old files on a schedule.
Expected result: The CSV lives in a restricted location, and any scheduled task runs the export on your chosen cadence.
Note
SYSTEM on a domain controller can read the recovery attributes. On a member server, a machine's SYSTEM account can't read recovery passwords, so run the task under a group-managed service account with delegated read access instead.
How to read the exported BitLocker key data
Interpret result
The CSV gives you one row per recovery key, not per computer. Each row pairs a device with a 48-digit recovery password (msFVE-RecoveryPassword), a recovery key ID taken from the object name, and the date the key was escrowed. To recover a drive, match the key ID shown on the BitLocker recovery screen to the RecoveryKeyId column, then use that row's password. A device can appear on several rows: one per encrypted volume, plus any keys created when a protector was reset. Rows where the password is blank or malformed point to a permissions problem or a partial escrow, not a usable key.
Normal result: Every encrypted, escrowed device shows at least one row with a well-formed 48-digit password and a recent creation date.
Abnormal result: Missing devices, blank passwords, or malformed values mean the backup policy wasn't in effect, the drive was encrypted before the policy applied, or your account can't read the recovery attribute.
Recovery password
123456-789012-345678-901234-567890-123456-789012-345678
48 digits in eight groups of six. This is what unlocks the drive.
Recovery key ID
{A4D7B98B-4D84-4622-AE99-FE623FEFC5FA}
Shown on the BitLocker recovery screen. Use it to pick the right row.
Multiple rows per computer
2 or more rows
Extra volumes or a rotated key, not a duplicate.
Troubleshooting
The query returns 'No BitLocker recovery keys found' even though BitLocker is on
Warning
Cause: The AD DS backup Group Policy wasn't configured, or the drives were encrypted before it applied, so nothing was ever escrowed.
Enable the policy under Computer Configuration > Policies > Administrative Templates > Windows Components > BitLocker Drive Encryption, choosing Save BitLocker recovery information to Active Directory Domain Services for each drive type. Existing drives need a fresh backup with manage-bde -protectors -adbackup C: -id {KeyProtectorID}.
Get-ADObject returns objects but the recovery password is blank
Warning
Cause: Your account can read the recovery objects but not the confidential msFVE-RecoveryPassword attribute.
Run as a member of Domain Admins, or have an admin delegate Read and Control Access on the msFVE-RecoveryPassword attribute to your group. Reading that attribute is restricted by design.
Get-ADDomain or Get-ADComputer fails with a module error
Note
Cause: The ActiveDirectory module isn't installed, or you're on PowerShell 7 without compatibility mode.
Install RSAT with Add-WindowsCapability -Online -Name Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0, then import the module. On PowerShell 7, use Import-Module ActiveDirectory -UseWindowsPowerShell.
The export is slow on a large domain
Note
Cause: The script checks every computer account for child recovery objects, which adds up across thousands of devices.
Scope each run to an OU with -SearchBase, run during off-peak hours, and add -ResultPageSize 1000 to the Get-ADComputer call to page results efficiently.
Frequently asked questions
What permissions do I need to export BitLocker recovery keys from Active Directory?
You need to read the computer objects and their msFVE-RecoveryInformation children, plus the confidential msFVE-RecoveryPassword attribute. Domain Admins have this by default. For a help desk, delegate Read and Control Access on that attribute to a specific group rather than granting broad rights.
Why does the script find no keys when BitLocker is clearly enabled?
BitLocker only writes recovery information to AD DS when Group Policy tells it to, and only for volumes encrypted after that policy applied. Turn on Save BitLocker recovery information to Active Directory Domain Services, then re-escrow existing drives with manage-bde -protectors -adbackup.
Can I export BitLocker keys from Microsoft Entra ID instead of on-premises AD?
Yes, but it's a different tool. Connect with Connect-MgGraph -Scopes BitLockerKey.Read.All, then run Get-MgInformationProtectionBitlockerRecoveryKey -All. The actual key only returns when you query a specific key ID with -Property key, and that request is written to the Entra audit log.
How do I check that an exported recovery password is valid?
A valid password is 48 digits in eight groups of six, like 123456-789012-345678-901234-567890-123456-789012-345678. Match it against the regex ^\d{6}-\d{6}-\d{6}-\d{6}-\d{6}-\d{6}-\d{6}-\d{6}$, or test it directly with manage-bde -unlock C: -RecoveryPassword <password>.
The export is slow on thousands of computers. How do I speed it up?
Scope each run to a single OU with -SearchBase, add -ResultPageSize 1000 to the Get-ADComputer call, and run separate exports per OU during off-peak hours. Narrowing the search does far more than any single tweak.
Is it safe to keep the exported CSV around?
Treat it as highly sensitive: it can unlock every listed drive. Store it on an access-controlled, encrypted location, restrict NTFS permissions to the admins who need it, and delete copies once you're done. Never email it or drop it on an open share.
Conclusion
Exporting BitLocker recovery keys from Active Directory is a short PowerShell job once the pieces are in place. Confirm the keys are escrowed, import the ActiveDirectory module, then walk the computer accounts and read the msFVE-RecoveryPassword attribute into a CSV. Validate the 48-digit format, spot-check one device in ADUC, and lock the file down. The same pattern scales from a single OU to the whole domain, and a scheduled task turns it into a recurring report.
With the ActiveDirectory module and the right permissions, one script pulls every escrowed BitLocker recovery key into a CSV you can search and audit.
Get-ADObject -LDAPFilter '(objectClass=msFVE-RecoveryInformation)' -Properties 'msFVE-RecoveryPassword' | Export-CsvSources4




