BitLocker and Self-Immolation
My primary device is corporate-owned, and contains a lot of corporate data. Policy says to have it secured by BitLocker, so I’ll have it secured by BitLocker. Perfectly reasonable, no?
However, I suspect something is wrong with this laptop’s TPM chip. Every so often, it decides that it won’t accept my BitLocker PIN, and requires I have the recovery passcode, all 48 digits of it. I save it to my SkyDrive (so I can read it via my phone if/when I need it), but sometimes I forget to do so. Both as an academic exercise, and as a way making it possible for me to schedule it as a task, I wrote the script below.
The two key takeaways are:
- Get-BitLockerVolume gives the BitLocker recovery data
- Start-Process PowerShell.exe –Verb RunAs escalates permissions
<# .Synopsis
Save the bitlocker recovery key.
.Description
Save the bitlocker recovery key for the specified drive, elevating itself to Administrator if possible.
.Notes
The self-elevation is brittle as hell. This script must be placed in a path that does not have special characters. Specifically '$home\Skydrive @ Microsoft\foo' does NOT work.
#>
param (
[string]$Path = "$home\SkyDrive\BitlockerRecovery\$env:ComputerName-$(Get-Date -Format 'yyyy-MM-dd').txt",
[string]$Drive = "c"
);
function Get-BitLockerRecoveryKey {
param (
[string]$Path = "$home\SkyDrive\BitlockerRecovery\$env:ComputerName-$(Get-Date -Format 'yyyy-MM-dd').txt",
[string]$Drive = "c"
);
# move existing key
if (Test-Path -Path $path) { mv $path ("$path-$(Get-Date -Format yyyyMMddhhmmss).txt"); }
# attempt to create destination folder if it doesn't exist
$pathDirName = Split-Path -Parent -Path $Path;
if (!(Test-Path -Path $pathDirName)) { New-Item -ItemType Directory -Path $path -ErrorAction SilentlyContinue | Out-null; }
if (Test-Path -Path $pathDirName) {
# If the folder exists, perform the heavy lifting
$scriptBlock = {
param (
[string]$Path = "$home\SkyDrive\BitlockerRecovery\$env:ComputerName-$(Get-Date -Format 'yyyy-MM-dd').txt",
[string]$Drive = "c"
);
$KeyProtector = (Get-BitLockerVolume -ErrorAction SilentlyContinue -MountPoint $Drive).KeyProtector | ? { $_.KeyProtectorType -eq 'RecoveryPassword'; }
if ($keyProtector) { "ID: $($KeyProtector.KeyProtectorId -replace '[{}]')`n`nKey: $($KeyProtector.RecoveryPassword)" | Out-File -FilePath $Path; }
} # $scriptBlock =
Invoke-Command -ScriptBlock $scriptBlock -ArgumentList $Path, $Drive;
if (Test-Path -path $Path) {
# if the file exists, this worked (but that's normally not the case)
$Path;
} else {
# if the file doesn't exist, elevate itself.
Start-Process PowerShell.Exe -WindowStyle Hidden -Verb RunAs -ArgumentList "-NoProfile -File $($MyInvocation.ScriptName) -Drive $Drive -Path $Path" -Wait;
if (Test-Path -Path $Path) {
# if the file exists, this worked
$Path;
} else {
# otherwise, carp and exit
Write-Warning "Unable to save BitLocker recovery key for drive ${drive}:";
} # if (Test-Path -Path $Path)
} # if (Test-Path $Path)
} else {
# if output folder doesn't exist, carp and exit
Write-Warning "Unable to find nor create $pathDirName";
} # if (Test-Path -Path $pathDirName)
} # function
# run it.
Get-BitLockerRecoveryKey -Path $Path -Drive $Drive;
Comments
Anonymous
November 01, 2013
Every now and then I also face the same problem: My corporate PC asks me to input the recovery key for no reason. I recently discovered that plugging in some USB devices might trigger this behaviour. I just have to unplug it, reboot and everything goes back to normal (i.e. prompting for PIN). I initially thought it only happened with external drives, but my 4G USB modem is also seen as an external USB drive though.Anonymous
August 09, 2014
Here's a cleaner way to do it: param ( $Path = "$homeOneDriveBitlockerRecovery$env:Computername.$((Get-WmiObject -Class Win32_Computersystem).Domain).txt".ToLower() ); if ( (New-Object -TypeName Security.Principal.WindowsPrincipal -ArgumentList ( [Security.Principal.WindowsIdentity]::GetCurrent() )).IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator) ) { if (!(Test-Path -Path $Path)) { if (New-Item -Path $Path -ItemType Directory) { Remove-Item -Path $Path; } } Import-Module -Name Bitlocker; Get-BitLockerVolume | % { $volumeData = $; $volumeData | % { "Drive: " + $.MountPoint; "GUID: " + $.KeyProtector[1].KeyProtectorId -replace '[{}]'; "Key: " + $.KeyProtector[1].RecoveryPassword } "" } | Set-Content -Path $Path Write-Host -ForegroundColor Green "Created file " -NoNewline; (Resolve-Path -Path $Path).ProviderPath; } else { Write-Error "Must be in a 'Run as Administrator' window."; }