Graph's API bitlocker/recoveryKeys calls return less than a handful of keys per call

Viewed 187

I have been following a couple of solutions to retrieve a list of Azure AD registered BitLocker keys using the MS Graph API. The code I am using is:

$AzureTokenURI = "https://login.microsoftonline.com/$TenantID/oauth2/v2.0/token"
$BitlockerURI = "https://graph.microsoft.com/v1.0/informationProtection/bitlocker/recoveryKeys"
$TokenRequestBody = "grant_type=password&username=$($SACred.UserName)&client_id=$ClientId&client_secret=$ClientSecret&password=$($SACred.GetNetworkCredential().Password)&scope=https://graph.microsoft.com/.default"
$TSStart = [datetime]::Now
$BitlockerKeys = @()
while ($BitlockerURI) {
    If (!$ResponseJSON -or ([datetime]::Now - $TSStart).TotalSeconds -gt ($ResponseJSON.expires_in - 300)) {
        $TSStart = [datetime]::Now
        $ResponseJSON = Invoke-WebRequest -Uri $AzureTokenURI -Method POST -Body $TokenRequestBody -UseBasicParsing |ConvertFrom-Json
        $BitlockerHeader = @{Authorization = "$($ResponseJSON.token_type) $($ResponseJSON.access_token)"; 'ocp-client-name' = 'BL_List_Keys_IDs'; 'ocp-client-version' = '1.0'}
        Write-Host "Token Renewed"
    }
    $BitlockerKeysResponse = Invoke-RestMethod -Uri $BitlockerURI -Headers $BitlockerHeader -Method Get
    $BitlockerKeys += $BitlockerKeysResponse.Value
    Write-Host $BitlockerKeys.Count.ToString().PadRight(6), (New-TimeSpan $TSStart ([datetime]::Now)).ToString('hh\:mm\:ss\.fff')
    $BitlockerURI = $BitlockerKeysResponse.'@odata.nextLink'
}

Now everything works, however when the keys are coming (little less than 5,000 in total) I realize that each call brings back just a few keys and I cannot seem to find a method to force the server side paging to a reasonable value (say a couple thousand keys per call). See the output below for the first 30 keys:

Keys Time Lapsed
1 00:00:13.343
5 00:00:24.452
6 00:00:31.984
10 00:00:40.765
14 00:00:49.171
18 00:00:56.577
22 00:01:03.937
27 00:01:12.468
30 00:01:20.218

This implies that just 5k keys take about 2 hours to download and this is nearly as bad as querying each device one by one which defeats the purpose of using the "/informationProtection/bitlocker/recoveryKeys" method in first instance. There is only one call in the list that returned 200 keys and that took 8 seconds which tells me that lapsed time does not depend on no of keys returned. Therefore the only way to make this method efficient is to force hundreds of keys to be returned at the same time. How can I force the API to return hundreds or thousands of keys per each call?

1 Answers

have you tried using $top={number} to get the specific number of calls that you want? Please refer to the paging - docs. Let us know if that worked for you and please feel free to reach out to us.

Related