Retrieving BitLocker keys from Azure AD with PowerShell


If you have BitLocker keys backed up to Azure Active Directory from your Azure AD joined computers, you’ve probably found yourself looking for a way to retrieve those keys using something other than the Azure portal. Of course users can retrieve the key themselves, but there are plenty of scenario’s imaginable where you’d want a support agent to be able to look up a user’s BitLocker key for them.

In Active Directory you can accomplish this by fetching the msFVE-RecoveryInformation objects associated with your AD computers, but there’s no comparable method for Azure AD (yet?). Get-AzureADDevice and Get-AzureADObjectByObjectId don’t expose nearly as much information about a device as Get-ADComputer and Get-ADObject!

Cue the “hidden” Azure portal API! I found out about this through a colleague’s blog post at Liebensraum. It enables you to perform various functions in Azure that you normally wouldn’t be able to using PowerShell.

Note: please be careful using this for production workflows as this is NOT supported by Microsoft.

I’ve written a function named Get-AzureADBitLockerKeysForUser which grabs all BitLocker recovery keys from Azure AD for a certain user.

Let’s walk through it step by step!

1. Prerequisites

You’ll need two modules installed for this: AzureAD (or AzureADPreview) and AzureRM, so go ahead and install those if you haven’t already.

You also need to be assigned one of the following Azure AD roles to be able to view BitLocker keys:

  • Global Administrator
  • Helpdesk Administrator
  • Security Administrator
  • Security Reader
  • Intune Service Administrator
  • Cloud Device Administrator

2. Connect to Azure AD and Azure RM

The function starts by connecting to both Azure AD and Azure RM, optionally using the supplied credential.

3. Get Access token

It then uses Jos Lieben’s method to retrieve an OAuth token for the endpoint, and creates the header to use in the API calls:

4. Find devices

Given the supplied user’s name or UserPrincipalName, it looks up all their Azure AD joined/registered devices:

5. Retrieve BitLocker keys

Finally, the script uses the API to retrieve the device records for the user’s devices and retrieve the available BitLocker key ID’s & recovery keys, along with the device name and drive type:

6. Output

The output of the function is an array of PSCustomObjects that you can use for further processing.

To wrap things up, here’s a screenshot of a sample run of the script:


Head over to my GitHub to grab a copy of the script, and let me know if you found it useful (or not)!

Introducing WindowsCompatibility for PowerShell Core

A major roadblock for a lot of Windows administrators in moving to PowerShell Core is the inability to use many of the popular Windows PowerShell modules they’ve become reliant on.

The WindowsCompatibility module for PowerShell Core, which saw the release of its first Release Candidate yesterday, aims to ease the transition from Windows PowerShell to PowerShell Core. It does this by using some clever black magic (okay, PSRemoting) to allow you to use your Windows PowerShell modules seamlessly from PowerShell Core!

Let’s take a closer look at this shiny new module.

1. Prerequisites

Obviously, you’ll need PowerShell Core for this. I’m using PowerShell 6.1.0, but any version from 6.0.0 and up should work. Grab a (preferably 64-bit) release from GitHub and install it, or use a script to download and install it for you. If you prefer using a tool like Chocolatey, run choco install pwsh (h/t @Jawz_84).


The WindowsCompatibility module uses remoting to work its magic, so you need to enable PSRemoting on your system. Start an elevated Windows PowerShell prompt and run

Check out the Microsoft Docs if you need more information on this.

2. Installation

Fire up PowerShell Core (I’m using PowerShell 6.1 here), and install the module by running the following:


3. Usage

The easiest way to get started with WindowsCompatibility is simply to import an existing Windows PowerShell module into your PS Core shell. Say you have the AzureADPreview module installed and would like to use it in PS Core. Simply run

and off you go!


You can now use all the cmdlets in the AzureAD module like you would in Windows PowerShell. What happens under the hood is that you’re actually remoted into a Windows PowerShell session on your own machine! This session is called the compability session. A little oddity is that the version number of the imported module is always set to 1.0, regardless of the version number of the corresponding Windows PowerShell module.

To see all the modules available for you to import, run

If you only want to see the modules that are available in Windows PowerShell but not in PS Core, run

This way you can easily see which modules you might need to import to complete a certain task.


A very nice feature of the module is being able to import modules from a different machine than localhost. Just use the -ComputerName parameter available in all the cmdlets of the module to connect to a remote machine.

If you have some code you’d like to run within the compatibility session, you can do so with

As long as the module containing the cmdlet you want to run is available in the session, you don’t even need to import the module.

Or build it out into a function which will run inside the compability session when called, using Add-WinFunction

This can come in handy when you’re using WindowsCompatibility in scripts. Note: you can only use positional parameters here, calling Invoke-HelloWorld -Name "YourName" won’t work.


And that’s about it! I think the WindowsCompatibility module is a great addition to PowerShell Core, and a must have for any Windows admin looking to start using PS Core in their daily workflows.

Since this is the release candidate I don’t expect any major change between this pre-release version and the eventual stable 1.0 version, but I’ll update this blog post as necessary if there any significant changes.