Hardware independent automatic Bitlocker encryption using AAD/MDM


Windows 10 delivers a "mobile-first, cloud-first" approach of simplified, modern management using cloud-based device management solutions such as Microsoft Enterprise Mobility Suite (EMS). This offers mobile users to be more productive regardless of location. At the same time organizations will require data to be safe, especially keeping 2018's GDPR in mind. Most organizations require a form of disk encryption like BitLocker.

In one of my previous blog posts you might have read about the requirement for InstantGo capable devices to automate BitLocker configuration on the device and backup the recovery key to the user's Azure AD account. Windows 1703, also known as the Creators Update, offers a wizard where users are prompted to start encryption regardless of the hardware used. This post describes how to fully automate BitLocker encryption without end-users being prompted.

Recently I received a few scripts that allow the triggering of a fully automated BitLocker encryption process regardless of hardware capabilities. The solution has been developed by Paul O Connor (DXC) and Adam Lyndersay (DXC) which leverages the previous powershell script work by Jan and Sooraj (DXC).

I've added some enhancements, wrapped them into an MSI - ready to be uploaded in Intune and deployed to a group of users. For specific scenarios where end-users are not part of the local admin group an alternative solution is available.

How does this solution work?

The TriggerBitLocker MSI attached to this blog does the following:

  • Deploys three files into C:\Program Files (x86)\BitLockerTrigger\
  • Imports a new scheduled task based on the included Enable_Bitlocker.xml

The scheduled task will run every day at 2PM and will do the following:

  • Run Enable_Bitlocker.vbs which main purpose is to call Enable_BitLocker.ps1 and make sure to run minimized.
  • In its turn, Enable_BitLocker.ps1 will encrypt the local drive and store the recovery key into Azure AD and OneDrive for Business (if configured)
    • The recovery key is only stored when either changed or not present

What if users are not part of the local admin group?

The first user that joins a device to Azure AD is a member of the local admin group by default (unless you are using Windows AutoPilot). If a second user – part of the same AAD tenant – logs on to the device, it will be a standard user. This is typically used in the scenario where a Device Enrollment Manager account takes care of the Azure AD join before handing over the device to the end-user. For this scenario you will find a modified MSI (TriggerBitlockerUser) at the bottom of this blog, some changes are:

  • The BitlockerTrigger scheduled task will run in the System Context and will:
    • Copy the recovery key to the Azure AD account of the user who joined the device to AAD.
    • Copy the recovery key to Systemdrive\temp (typically C:\Temp) temporarily.
  • A new script MoveKeyToOD4B.ps1 is introduced and runs daily via a scheduled task called MoveKeyToOD4B. This scheduled task runs in the users context. The recovery key will be moved from systemdrive\temp to the OneDrive for Business\recovery folder.

If you are going to use this alternative scenario, make sure to download TriggerBitlockerUser at the bottom of this post. Deploy this via Intune to the group of end-users, not the Device Enrollment Manager group/account used to join the device to Azure AD.

How can users get access to their recovery key?

This recovery key is written to two locations, both the Azure AD account and into a recovery folder in the OneDrive for Business (if configured). Users can retrieve the recovery key via http://myapps.microsoft.com and navigating to their profile, or in their OneDrive for Business\recovery folder.

Azure AD (make sure you log on with the account used to join the device to AAD):

OneDrive for Business:

Important to know:

  • After the script has run (most likely after 2 PM) a reboot will be required before the initial BitLocker encryption starts - users will be prompted. You could force a reboot by changing the scripts. The recovery key will be written to Azure AD and/or OneDrive For Business the next time the scheduled task is run, this could be 2 PM the next day.
  • Upload the MSI to Intune as a "Line-of-business" app. I've successfully tested by deploying towards a User Group as "required" using the new portal at http://portal.azure.com.
  • The script doesn't take any potential 3rd party encryption software into account. Only deploy this MSI to devices where BitLocker will be the only disk encryption solution in place.
  • BitLocker won't start the encryption process if any removable drives are attached/mounted. Automatic removal can also be added to the script (see the comment from Jos Lieben below).
  • Please test this MSI on your own devices and in your own environment before broadly deploying.
  • This solution has only been tested on Windows 10 1703 x64. You can even test on a Virtual Machine, as long as you assign a Virtual TPM.
  • Consider using Microsoft Intune Compliance policies in combination with Conditional Access to make sure only BitLocker encrypted devices can access company resources.

A lot of time and testing has gone into this project, if you find it useful - please consider leaving a reply.

Changelog:

  • June 21 - 2017
    • Uninstall removes the scheduled task(s)
    • If available, uses new PowerShell commandlet to backup key to AAD
    • Use TLS1.2 when connecting to AAD
    • Better error handling and minor reliability fixes in script
  • August 1 - 2017
    • Better error handling in non-admin scenario (TriggerBitlockerUser).

Downloads:

Comments (33)

  1. Joonas Pakkanen says:

    Cheers!

  2. Carl says:

    Thanks!

  3. Jos Lieben says:

    Nice, I would also add removing any media before attempting to encrypt, with this for example:

    try{
    # Automatically unmount any iso/dvd’s
    $Diskmaster = New-Object -ComObject IMAPI2.MsftDiscMaster2
    $DiskRecorder = New-Object -ComObject IMAPI2.MsftDiscRecorder2
    $DiskRecorder.InitializeDiscRecorder($DiskMaster)
    $DiskRecorder.EjectMedia()
    }catch{
    Throw
    }

    try{
    # Automatically unmount any USB sticks
    $volumes = get-wmiobject -Class Win32_Volume | where{$_.drivetype -eq ‘2’}
    foreach($volume in $volumes){
    $ejectCmd = New-Object -comObject Shell.Application
    $ejectCmd.NameSpace(17).ParseName($volume.driveletter).InvokeVerb(“Eject”)
    }
    }catch{
    Throw
    }

    1. Thanks for the suggestion and sharing the script! in a future version it will be included, Bitlocker encryption won’t start if removable drives are attached.

      1. andor.oudt says:

        any chance you already know when you will be updating the script and include the suggested elements ?

  4. Brett Hoggins says:

    Hi, have been testing the TriggerBitlockerUser MSI, think I have found a bug as it doesn’t move they key to OD4B:
    in Enable_Bitlocker.ps1, the script saves the recovery key in $env:system\temp\ — Possible typo? This seems to result in C:\temp anyway. (“\temp” == root of drive)
    in CopyKeyToOD4B.ps1, the script attempts to find the key file in $env:systemroot\temp\ — this is C:\Windows\temp. It fails to find the file and exits.
    I think in both cases the intended path was $env:SystemDrive ?
    If you want, flick me an email and I can send you a revised copy of the scripts. 🙂

    1. Thanks – this has been fixed shortly after your comment.

  5. niall says:

    hi
    interesting article, thanks, do you think it will work with Intune’s BitLocker updates released recently ? I’ve blogged about how to implement BitLocker with Intune here https://www.windows-noob.com/forums/topic/15514-how-can-i-configure-bitlocker-settings-on-windows-10-devices-managed-by-intune/#comment-59070 but the issue is the user must click on the the notification and then click next for anything to start,

    I want to automate this 100%, will this help ?

    what if a user is NOT a local admin (as they should be in 2017) ?

    cheers
    niall

    1. This is solution should help you automate Bitlocker enforcement, also when users are not local admin

      1. Niall Brady says:

        hi
        I’ve now tested this and it deploys the MSI no problem, and runs the script when it is supposed to, however (in my test environment) it does nothing, and the task scheduler does not reveal the problem in the task history, as the vbs runs just fine…

        unfortunately there’s no logging built into the powershell script to I had to set-executionpolicy unrestricted and manually run the powershell script, once done I could see the problem (on my hyperv Gen2 vm’s with the local GPO configured to allow for bitlocker)

        Enable-BitLocker : An external key or password protector is required to enable BitLocker on an
        operating system volume without a valid TPM.
        At C:\Program Files (x86)\BitlockerTrigger\Enable_BitLocker.ps1:36 char:13
        + Enable-BitLocker -MountPoint $OSDrive -TpmProtector -Err …

        so have you not tested this scenario, it would be great to have it working as I want to demo it and point it back here 🙂

        also, it would be a very good idea to add logging to your script so that problems like this can be read easily without resorting to running the script to see where it’s failing (i.e. outside of the scheduled task)

        1. Niall Brady says:

          after enabling Virtual TPM support in hyperv (windows 10 v 1703) i got further but now the powershell script is complaining about media

          I’ll fix these but once again, great solution you have here which could be awesome IF you added logging to the PowerShell script

          Add-TpmProtectorInternal : BitLocker Drive Encryption detected bootable media (CD or DVD) in the
          computer. Remove the media and restart the computer before configuring BitLocker. (Exception from
          HRESULT: 0x80310030)
          At C:\Windows\system32\WindowsPowerShell\v1.0\Modules\BitLocker\BitLocker.psm1:2095 char:31
          + … $Result = Add-TpmProtectorInternal $BitLockerVolumeInternal.MountPo …
          + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          + CategoryInfo : NotSpecified: (:) [Write-Error], COMException
          + FullyQualifiedErrorId : System.Runtime.InteropServices.COMException,Add-TpmProtectorInterna
          l

          C:\Program Files (x86)\BitlockerTrigger\Enable_BitLocker.ps1 : Error while setting up AAD
          Bitlocker, make sure that you are AAD joined and are running the cmdlet as an admin: Cannot
          validate argument on parameter ‘KeyProtectorId’. The argument is null or empty. Provide an
          argument that is not null or empty, and then try the command again.
          + CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
          + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Enable_BitLocker.
          ps1

          the reason you need to add logging is the Scheduled task will NOT report any error as it runs the VBS just fine, you have to manually run the PowerShell script to actually get the error output above

          1. Hi Niall, this script wont run when media is inserted. A next version will “eject” media before doing anything. Logging is definitely a nice to have…

  6. Berry van Bree says:

    Thanks for sharing Pieter!

    How does this work when you deploy devices with Provisioning Packages?

    1. Not tested but assuming you are using a Provisioning Package to join the device to Azure AD, this solution should still work as long as you deploy “TriggerBitlockerUser (MSI – for non local admin scenarios)” via Intune.

      1. i says:

        hi, can this be deployed thru sccm? or is intune preferred?

        1. Only tested via Intune. If you have ConfigMgr connected to Intune it should deploy (not tested).

  7. gary.chen says:

    HI, i found that the MSI package only can encrypt the OS drive (C:), but can’t encrypt data drive (D:).

    1. It only encrypts the OS drive. You could change the scripts to also encrypt additional partitions/drives or choose to simply use one partition only (most likely C:). The need for a separate data partition has decreased over years.

  8. Hmm, the title says “Hardware independent”. Yet, in the important to know section, it references a TPM chip. Does it require TPM or not?

    1. Hi Johan, technically BitLocker does not require a TPM but you will have to fallback to USB thumb drives – not recommended for various reasons. Unattended BitLocker encryption with the recovery key stored in AAD previously required specific InstantGo hardware, this should work non-InstantGo capable devices.

  9. Steve says:

    I may have missed this, but when using Autopilot, can Intune still be used to enforce bit locker? Because there is now no local admin.

    1. Intune policies remain unaffected, it runs in the context of a different user (not the local admin)

  10. william Wu says:

    Hi, thanks for the MSI first. Could you please give me a version that can also encrypt all drivers in case the computer have more then one partitions?

  11. Niall Brady says:

    hi Pieter, I’ve created a new Powershell script based on yours and your msi, and it includes logging, logic and a reboot, you can see it here

    https://www.windows-noob.com/forums/topic/15696-configuring-bitlocker-in-intune-part-2-automating-encryption/

    thanks for your work !

    cheers
    niall

  12. Stephen Skarlatos says:

    I am using Windows AutoPilot. I created the App in Intune with the TriggerBitlockerUser.msi. The app is installed successfully, I see the MoveKeyToOD4B.ps1 trigger, but Bitlocker is not enabled. What am I doing wrong? Thanks if this works it will be really helpful for both regular and autopilot deployments.

    1. Stephen Skarlatos says:

      I thought the script would run immediately after install, but I had to wait overnight. Once I rebooted Bitlocker is on. A great side benefit is that user can’t turn off. Thank you.

  13. Pieter says:

    Hi Pieter,

    I have tried to run the TriggerBitlockerUser script but with no good result. The script installs fine. After installation the document is created where the bitlocker key should be written down. But the file is blank. No information is added to the file. Looks like a rights issue. I checked the scheduled task but I can verrify that the task is run under the local system account. Can you please assist? Am I overlooking something?

    Cheers!
    Pieter

  14. Hi, and thanks for your work. How about handling TPM + PIN scenarios? I’m thinking about adding a pop up to ask the user’s PIN and add a new protector. Did you ever test this scenario?

  15. Niklas Jern says:

    Hi Pieter,
    Great post, as always.
    However I have one question, you mention “In one of my previous blog posts you might have read about the requirement for InstantGo capable devices to automate BitLocker configuration on the device and backup the recovery key to the user’s Azure AD account. ”
    I’m trying to find out more information about the part were InstantGo devices automate the bitlocker process, but without any luck. Do you happen to have any links you can share on this subject?

  16. JohnM says:

    Hi @pieter,

    Would you still choose to deploy Bitlocker via custom MSI package now that new features are available to deploy powershell scripts in Intune OR new Bitlocker options via device configuration profiles (Endpoint protection (Win10Ent only) or custom SCP)?

    Regards,
    JM

  17. MrShannon says:

    I curious about possibly invoking this by using the native Powershell deployment option instead of a pre-packaged MSI. I assume we would need a script that creates the the scheduled task(s) and creates the other scripts the tasks run. I believe the scripts run as System already, so it should work for non-admin users just the same.

    https://docs.microsoft.com/en-us/intune/intune-management-extension

    With some refactoring and wrapping, it it seems like it would be possible with the added benefit of being able to review / alter the script. I’m not totally certain if this would be a better option that the MSI route, but might be interesting to experiment.

Skip to main content