Retrieving BitLocker keys from Azure AD with PowerShell

Alt

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 main.iam.ad.ext.azure.com 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:

Alt

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

5 Comments

  1. I was able to login to AD/RM successfully when the popup’s appeared but then get this;

    Invoke-RestMethod : {“error”:”invalid_request”,”error_description”:”AADSTS900144: The request body must contain the
    following parameter: ‘refresh_token’.\r\nTrace ID: 44f0f34f-7f6b-4a2e-92dd-8cfd59702800\r\nCorrelation ID:
    0bf45b52-5dc6-4b26-9e94-5df3ff1c8366\r\nTimestamp: 2019-01-04
    12:50:58Z”,”error_codes”:[900144],”timestamp”:”2019-01-04
    12:50:58Z”,”trace_id”:”44f0f34f-7f6b-4a2e-92dd-8cfd59702800″,”correlation_id”:”0bf45b52-5dc6-4b26-9e94-5df3ff1c8366″}
    At line:53 char:17
    + … $apiToken = Invoke-RestMethod “https://login.windows.net/$tenantId/oa …
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebExc
    eption
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
    Invoke-RestMethod :
    401 – Unauthorized: Access is denied due to invalid credentials.
    Server Error

    401 – Unauthorized: Access is denied due to invalid credentials.
    You do not have permission to view this directory or page using the credentials that you supplied.

    At line:65 char:25
    + … viceRecord = Invoke-RestMethod -Uri $url -Headers $header -Method Get
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebExc
    eption
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
    Invoke-RestMethod :
    401 – Unauthorized: Access is denied due to invalid credentials.
    Server Error

    401 – Unauthorized: Access is denied due to invalid credentials.
    You do not have permission to view this directory or page using the credentials that you supplied.

    At line:65 char:25
    + … viceRecord = Invoke-RestMethod -Uri $url -Headers $header -Method Get
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebExc
    eption
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand

    Reply

    1. It’s still working for me! Using AzureADPreview 2.0.2.5 and AzureRM.Profile 5.8.2. Does your account have sufficient rights in Azure AD?

      Reply

  2. Can you test Step 3 and let me know if it’s still working? I’m getting an error when trying to get an $apiToken…
    Invoke-RestMethod : {“error”:”invalid_request”,”error_description”:”***********: The request body must contain the following parameter:

    Reply

    1. It’s still working for me! Using AzureADPreview 2.0.2.5 and AzureRM.Profile 5.8.2. Does your account have sufficient rights in Azure AD?

      Reply

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.