For some reason, Bitlocker will not resume on some remote Dell workstations. I suspect this has to deal with not being connected to the domain when booting up/logging in. After many attempts, I finally got a working script that will resume Bitlocker even if they are not on the VPN.
This has been driving me crazy for months. Hopefully this will help others.
Evaluation
# Check BitLocker status on C:
$bitlockerStatus = Get-BitLockerVolume -MountPoint "C:" | Select-Object -ExpandProperty ProtectionStatus
# BitLocker Status Legend:
# 0 = Off
# 1 = On
# 2 = Suspended
# Return 1 (non-compliant) if BitLocker is suspended (status = 2)
# Return 0 (compliant) if BitLocker is enabled (status = 1)
# Return 1 (non-compliant) if BitLocker is off or any other status
if ($bitlockerStatus -eq 2) {
Write-Output "BitLocker is suspended."
exit 1
} elseif ($bitlockerStatus -eq 1) {
Write-Output "BitLocker is enabled and active."
exit 0
} else {
Write-Output "BitLocker is not enabled or in unknown state."
exit 1
}
Remediation
# Define registry path and value
$regPath = "HKLM:\SOFTWARE\Policies\Microsoft\FVE"
$valueName = "OSActiveDirectoryBackup"
# Check if the registry path exists
if (-not (Test-Path $regPath)) {
Write-Host "Registry path does not exist: $regPath" -ForegroundColor Yellow
Write-Host "The key is not configured (effectively disabled)." -ForegroundColor Green
exit 0
}
# Check if the value exists
try {
$currentValue = Get-ItemProperty -Path $regPath -Name $valueName -ErrorAction Stop
$valueData = $currentValue.$valueName
Write-Host "Current value of $valueName`: $valueData" -ForegroundColor Cyan
# Store the original value
$originalValue = $valueData
# If the value is 1 (enabled), disable it temporarily
if ($valueData -eq 1) {
Write-Host "The key is ENABLED. Proceeding to disable..." -ForegroundColor Yellow
# Disable the key by setting it to 0
Set-ItemProperty -Path $regPath -Name $valueName -Value 0 -Type DWORD -Force
# Verify the change
$newValue = (Get-ItemProperty -Path $regPath -Name $valueName).$valueName
if ($newValue -eq 0) {
Write-Host "SUCCESS: The key has been disabled (set to 0)." -ForegroundColor Green
} else {
Write-Host "WARNING: The key may not have been disabled correctly." -ForegroundColor Red
}
} else {
Write-Host "The key is already DISABLED (value is $valueData)." -ForegroundColor Green
}
# ============================================
# Resume script
# ============================================
Write-Host "--- Starting BitLocker Resume Script ---"
# Get all fixed drives (DriveType 3 = fixed disk)
try {
$fixedDrives = Get-CimInstance Win32_LogicalDisk -Filter "DriveType=3" -ErrorAction Stop
if ($null -eq $fixedDrives -or $fixedDrives.Count -eq 0) {
Write-Host "No fixed drives found on this system. Exiting."
exit 0
}
}
catch {
Write-Error "Failed to retrieve fixed drive information: $($_.Exception.Message)"
exit 1 # Exit with an error code for Automox failure
}
foreach ($drive in $fixedDrives) {
$driveLetter = $drive.DeviceID
Write-Host "Processing drive ${driveLetter}..."
try {
# Get BitLocker volume info via CIM
$volume = Get-CimInstance -Namespace 'ROOT/CIMV2/Security/MicrosoftVolumeEncryption' `
-ClassName Win32_EncryptableVolume -Filter "DriveLetter='${driveLetter}'" `
-ErrorAction Stop
if ($null -eq $volume) {
Write-Host "${driveLetter}: Not a BitLocker-enabled volume or not found."
continue # Move to the next drive
}
# Check protection status (3 = Protection Paused)
$protectionStatus = $volume.ProtectionStatus
# Get suspend count
$suspendInfo = $null
$suspendCount = -1 # Default to unknown
try {
$suspendInfo = Invoke-CimMethod -InputObject $volume -MethodName "GetSuspendCount" -ErrorAction Stop
if ($null -ne $suspendInfo) {
$suspendCount = $suspendInfo.SuspendCount
}
}
catch {
Write-Host "${driveLetter}: Could not get suspend count. Error: $($_.Exception.Message)" # Use Write-Host here, not critical failure
}
if ($protectionStatus -eq 3 -or $suspendCount -gt 0) {
if ($suspendCount -gt 0) {
Write-Host "${driveLetter}: BitLocker is suspended with $suspendCount reboots remaining. Attempting to resume..."
} else {
Write-Host "${driveLetter}: BitLocker protection status is 'Paused'. Attempting to resume..."
}
# Enable key protectors (force resume)
$result = Invoke-CimMethod -InputObject $volume -MethodName "EnableKeyProtectors" -ErrorAction Stop
# Check return value (0 indicates success)
if ($result.ReturnValue -eq 0) {
Write-Host "${driveLetter}: BitLocker successfully resumed."
}
else {
$errorMessage = switch ($result.ReturnValue) {
201 { "Access Denied (insufficient privileges)." }
202 { "An invalid parameter was passed." }
203 { "The volume is already fully encrypted or not encrypted." }
204 { "The volume is not in a suspended state." }
default { "Unknown error code: $($result.ReturnValue)" }
}
Write-Error "${driveLetter}: Failed to resume BitLocker. Return code: $($result.ReturnValue) - $errorMessage"
# Consider if failure to resume one drive should fail the entire policy.
# For now, it will continue to the next drive but mark an error.
}
}
else {
Write-Host "${driveLetter}: BitLocker is not suspended, already fully protected, or not applicable (ProtectionStatus: $protectionStatus, SuspendCount: $suspendCount)."
}
}
catch {
# Catch specific CIM errors or general errors during volume processing
if ($_.Exception -is [System.Management.Automation.CmdletInvocationException] -and $_.Exception.InnerException -is [System.Management.ManagementException]) {
$cimException = $_.Exception.InnerException
Write-Error "${driveLetter}: CIM Error - $($cimException.Message) (Error Code: $($cimException.ErrorCode))"
}
else {
Write-Error "${driveLetter}: An unexpected error occurred - $($_.Exception.Message)"
}
# Continue to next drive even if one fails
}
}
Write-Host "--- BitLocker Resume Script Finished ---"
Write-Host "Custom script completed." -ForegroundColor Cyan
# ===================================================
# Check if original value was 0, restore if it was 1
# ===================================================
if ($originalValue -eq 1) {
Write-Host "`nRestoring registry value to 1..." -ForegroundColor Yellow
Set-ItemProperty -Path $regPath -Name $valueName -Value 1 -Type DWORD -Force
# Verify restoration
$restoredValue = (Get-ItemProperty -Path $regPath -Name $valueName).$valueName
if ($restoredValue -eq 1) {
Write-Host "SUCCESS: The key has been restored to 1." -ForegroundColor Green
} else {
Write-Host "WARNING: The key may not have been restored correctly." -ForegroundColor Red
}
} else {
Write-Host "`nOriginal value was 0. No restoration needed." -ForegroundColor Green
}
} catch {
Write-Host "Registry value does not exist: $valueName" -ForegroundColor Yellow
Write-Host "The key is not configured (effectively disabled)." -ForegroundColor Green
}