powershellmicrosoft-graph-apibitlockermicrosoft-graph-intune

How to get bitlocker recovery keys for Intune device with MS Graph


I am trying to get a list of all devices from Intune and their associated bitlocker keys, if there is one. I am able to get a list of all devices no problem, but I can not find the correct permissions to get the bitlocker keys. I am using Powershell for 2 methods: one using the Graph cmdlets provided by Microsoft, and another using the API and Invoke-RestMethod. Both methods are using the same service principal for authentication.

Method 1:

C:\> Get-MgInformationProtectionBitlockerRecoveryKey
Get-MgInformationProtectionBitlockerRecoveryKey_List1: Failed to authorize, token doesn't have the required permissions.

Method 2:

C:\> $Params = @{
>>     Uri = "https://graph.microsoft.com/beta/informationProtection/bitlocker/recoveryKeys"
>>     Headers = @{
>>         Authorization = "Bearer $Token"
>>         ConsistencyLevel = "eventual"
>>     }
>>     ErrorAction = 'Stop'
>> }
C:\> (Invoke-RestMethod @Params)
Invoke-RestMethod: {"error":{"code":"authorization_error","message":"Failed to authorize, token 
doesn't have the required permissions.","innerError":{"date":"2023-11-10T19:18:31",
"request-id":"xxxxxxxxxxxxxxxx","client-request-id":"xxxxxxxxxxxxxxxxxxxx"}}}

The service principal we are using has always worked in the past. The service principal was granted both the Global Reader and Intune Administrator roles, as well as the BitlockerKey.Read.All app permission. Note that the BitlockerKey.Read.All had to be set to Delegated, as no Application permissions were available. I have been following the instructions from this documentation from Microsoft saying that it has to be set to Delegated but you must grant certain role access, however I am still unable to get authorization.

Does anybody know how to properly authenticate, or know of a way to get the bitlocker keys?

Edit: I am providing the Powershell used to authenticate for both methods.

Method 1: Connect-MgGraph

The $ClientId is the id of the service principal, found in Entra > Identity > Applications > App Registrations. The $ClientSecret is password.

$Params = @{
    ClientId = $ClientId
    ClientSecret = $ClientSecret
    TenantId = $TenantId
    ForceRefresh = $true
    ErrorAction = 'Stop'
}
$AccessToken = (Get-MsalToken @Params).AccessToken
Connect-MgGraph -AccessToken $AccessToken -ErrorAction Stop |Out-Null

Method 2: Invoke-RestMethod with the Graph API

The $Credential variable is the credentials of the same service principal used in Method 1.

$Params = @{
    Uri = "https://login.microsoftonline.com/$TenantId/oauth2/v2.0/token"
    Body = @{
        'client_id' = $Credential.UserName
        'scope' = 'https://graph.microsoft.com/.default'
        'client_secret' = $Credential.GetNetworkCredential().password
        'grant_type' = 'client_credentials'
    }
    Method = 'Post'
    ContentType = 'application/x-www-form-urlencoded'
    ErrorAction = 'Stop'
}
$GraphAccessToken = Invoke-RestMethod @Params |Select-Object -ExpandProperty access_token
[pscustomobject]@{
    GraphAccessToken = $GraphAccessToken
}

Edit 2: I tried the steps in the verified answer of this Stackoverflow forum about adding the additional Uri in the Authentication page in Entra, but with no luck. It still yields the exact same results. I also tried using Get-MsalToken instead of Invoke-RestMethod to get the access token. This had no impact as well.


Solution

  • I found a solution for those wondering. Since I was only doing a one-time export, I just ran it from my own personal account, although a service account may work just as fine. I did not use the service principal to authenticate. Here is the basic code:

    Connect-MgGraph -Scopes 'BitLockerKey.Read.All' -TenantId 'xxxxxxxxxxxxxx'
    $BitLockerKeys = Get-MgInformationProtectionBitlockerRecoveryKey -All