BitLocker state of encrypted, but no Key Protectors and Protection off. Resolving with Intune.

This post describes a recent issue I had with BitLocker drive encryption. It started with Hybrid AAD joined devices showing successfully encrypted, but keys are not uploading to Azure AD, and the encryption settings were not really being deployed. Further investigation revealed a strange BitLocker state on most of the machines. If you find yourself in this situation, I caution you to test this fix thoroughly in your environment and/or modify it accordingly. The script was developed for this exact situation but can be modified to fit other situations if needed.   

Here is a quick example of what I inherited for this client. HAADJ devices showing a successful deployment of BitLocker, but no recovery keys in AAD.  

A manage-bde -status shows the below output on the affected machines: 

I had never seen BitLocker in this state before. With no key protectors, no recovery keys can be generated, and the drive will have a protection state of off.  So, how did it get this way? Well, that part is still a mystery. I had to try reproducing this on a machine so I could do some testing.   

On a test device, I manually encrypted the drive. We can see after the encryption complete and after a reboot, Protection was On with Key Protectors of TPM and Numerical Password: 

Now I needed to try getting this to the state where the drive was encrypted, but protection was off with no key protectors. If we use the command “Manage-bde -protectors -delete c:” we can remove all key protectors, which also disables protection: 

And the bitlocker status after the above command. OK, so now we have the issue reproduced on a test machine.  

As previously mentioned, these are Hybrid AADJ machines, which are known to have issues with silent BitLocker encryption using built-in Intune encryption policies. Nickolaj Anderson wrote an awesome PowerShell script (blog available here (https://msendpointmgr.com/2019/10/31/silently-enable-bitlocker-for-hybrid-azure-ad-joined-devices-using-windows-autopilot/) to resolve this issue. We simply push it out as a Win32 app. So, my first test was to run this script against one of the machines. However, the script failed to do what I wanted since the drive is already marked as encrypted.  

After some more manual testing, I found that if I decrypted the drive (manage-bde -off c: ), I could use Nickolaj’s script and the machine would properly encrypt and upload the recovery key to AAD. The next issue I had, was there were over 100 devices. Most of the devices had the BitLocker status of Encrypted, but no key protectors and no recovery keys. Some were properly encrypted, and others had encryption off. This was a messy situation without a native easy way to fix it. 

I needed to make a custom script in an attempt to resolve this quickly and in an automated way. Lucky for me, Nickolaj’s script already accomplishes encrypting and uploading recovery keys to AAD. I needed this new script to do several things: 

  1. Check the status of the drive encryption on the target machine 
  1. If it matches the settings I wanted and was properly encrypted, upload the recovery key to AzureAD 
  1. If the system drive is decrypted and has BitLocker disabled, encrypt the drive with Nickolaj’s script, which also uploads the recovery key to AAD 
  1. If it was in the odd state of the drive being encrypted, but no Key Protectors and Protection disabled, decrypt the drive, wait for decryption to complete, and then run Nickolaj’s script.  

The resulting script is on GitHub and shown below:  

#Script identifies the current status of bitlocker and takes action depending on current state
$Loop = $true
$BitlockerStatus = Get-BitLockerVolume -MountPoint C:
If ((($BitlockerStatus.VolumeStatus -eq 'FullyEncrypted') -and ($BitlockerStatus.KeyProtector.KeyProtectorType -contains 'Tpm')) -and ($BitlockerStatus.ProtectionStatus -eq 'On'))
    {
        Write-Host -f Yellow "Drive is encrypted with correct configuration. Uploading recovery key to Azure AD"
        $BLV = Get-BitLockerVolume -MountPoint "C:"
        BackupToAAD-BitLockerKeyProtector -MountPoint "C:" -KeyProtectorId $BLV.KeyProtector[1].KeyProtectorId
    }
If ((($BitlockerStatus.VolumeStatus -eq 'FullyDecrypted') -and ($BitlockerStatus.KeyProtector.KeyProtectorType -notcontains 'TPM')) -and ($BitlockerStatus.ProtectionStatus -eq 'Off'))
    {
        Write-Host -f Yellow "Drive is decrypted. Encrypting and Uploading recovery Key to AzureAD"
        & ".\Enable-Bitlocker.ps1"
    }
If ((($BitlockerStatus.VolumeStatus -eq 'FullyEncrypted') -and ($BitlockerStatus.KeyProtector -notcontains 'Tpm')) -and ($BitlockerStatus.ProtectionStatus -eq 'Off'))
    {
        Write-Host -f Yellow "Drive is Encrypted without protection and no Key Protectors. Disabling Bitlocker and re-encrypting drive with corporate settings. Decryption Key will be uploaded to Azure AD."
        Disable-Bitlocker -MountPoint "C:"
        while($Loop){
        [int]$encryptionpercentage = Get-BitlockerVolume | Select-Object -expand EncryptionPercentage
        if($encryptionpercentage -ne 0)
        {
        #Write-Progress -Activity "Bitlocker Drive Decryption Status" -Status "Decrypting" -PercentComplete $encryptionpercentage
        Start-Sleep -Seconds 5
        }else{
        #Write-Progress -Activity "Bitlocker Drive Decryption Status" -Completed
        $Loop = $false
        }
    }
        & ".\Enable-Bitlocker.ps1"
    }

Lastly, this needed to be deployed to the machines. I needed to make a new install detection script, also, since I needed to make sure it looked for more than just the drive being encrypted. So, the new detection script looks to make sure the drive is encrypted, TPM is listed as a Key Protector, and Protection is Enabled. 

$BitLockerOSVolume = Get-BitLockerVolume -MountPoint $env:SystemRoot 

If ((($BitLockerOSVolume.VolumeStatus -eq 'FullyEncrypted') -and ($BitLockerOSVolume.KeyProtector.KeyProtectorType -contains 'Tpm')) -and ($BitLockerOSVolume.ProtectionStatus -eq 'On')) { 
    return 0 
}  

If I manually run (as system) the FixBrokenBitlocker script, it works as intended. I tested in all three possible BitLocker states I was dealing with (decrypted, encrypted properly, encrypted with no key protectors or protection). Here is a sped-up gif to show the script running against a machine encrypted with no key protectors, which is what most of the machines I needed to resolve. We can see that it detects the state of BitLocker, decrypts the volume, and then calls Nickolaj’s script to encrypt the machine and upload the recovery key to AAD.  

Now that we confirmed it functions as intended, let’s wrap our scripts as a Win32 app, configure the app, and deploy this to some test devices. Place Nickolaj’s enable-bitlocker.ps1 script in the same directory as the FixBrokenBitlocker.ps1 script, and wrap the scripts as a .intunewin file with FixBrokenBitlocker.ps1 as the install file.  

Create your Win32 app and upload the .intunewin file we just created.  

Provide a name and description: 

For the install command, we will use powershell.exe -executionpolicy bypass .\FixBrokenBitlocker.ps1. We don’t need an uninstall command, so we can just put cmd.exe so there is a value. Choose System for the install behavior.  

Use a custom detection script, and upload the get-BitLockervolume script we modified earlier.  

Finish the rest of the app creation and assign to your device group.  

Here are two of the machines prior to pushing out the Win32 App. We can see this one is in the partial state, where the drive is encrypted, but protection is off with no key protectors. The other is fully decrypted: 

After the script was deployed, they both were in the correct state: 

With recovery keys available in Azure AD: 

And marked as compliant for BitLocker encryption: