You are using the client credentials flow to obtain a token, this flow requires Application permissions, not Delegate ones. So either obtain a token in the context of a user (with sufficient permissions and the above app), or replace the Delegate permissions entries you have added with the corresponding Application permissions ones.
How to access : Get-MgInformationProtectionBitlockerRecoveryKey
Hi all, I come to his place to request your help please. I try to request Bitlocker recovery key from my Entra Hybrid joined computers. Following the documentation I created a registered app and granted delegated permission to BitlockerKey.Read.All, Device.Read.All and User.Read.all
But no matter how I try to connect searching solution on Internet, I always receive : #Get-MgInformationProtectionBitlockerRecoveryKey_List: Failed to authorize, token doesn't have the required permissions.
Here the way i tried :
First :
$tenantid="MyTenantId"
$appid="MyAppId"
$SecuredPassword="SecretOfMyApp"
$SecuredPasswordPassword = ConvertTo-SecureString -String $SecuredPassword -AsPlainText -Force
$ClientSecretCredential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $appid, $SecuredPasswordPassword
Connect-MgGraph -TenantId $tenantID -ClientSecretCredential $ClientSecretCredential -NoWelcome
#Connexion is OK
Get-MgInformationProtectionBitlockerRecoveryKey
#Get-MgInformationProtectionBitlockerRecoveryKey_List: Failed to authorize, token doesn't have the required permissions.
Second :
$tenantid="MyTenantId"
$appid="MyAppId"
$AppSecret="SecretOfMyApp"
Import-Module Microsoft.Graph.Authentication
Import-Module Microsoft.Graph.Identity.SignIns
$body = @{
grant_type = "client_credentials";
client_id = $AppId;
client_secret = $AppSecret;
scope = "https://graph.microsoft.com/.default";
}
$response = Invoke-RestMethod -Method Post -Uri https://login.microsoftonline.com/$tenantid/oauth2/v2.0/token -Body $body
$accessToken = $response.access_token
$accessToken
$SecuredaccessToken = ConvertTo-SecureString -String $accessToken -AsPlainText -Force
#Select-MgProfile -Name Beta
Connect-MgGraph -AccessToken $SecuredaccessToken -NoWelcome
#connexion OK
Get-MgInformationProtectionBitlockerRecoveryKey
#Get-MgInformationProtectionBitlockerRecoveryKey_List: Failed to authorize, token doesn't have the required permissions.
Third (Worst because blocking with MFA) :
$TokenBody = 'grant_type=password' + '&client_id=MyAppID' + '&username=MyAdmAccount@contoso.fr' + '&password=MyOwnPassword' + '&resource=https://graph.microsoft.com' + '&client_secret=MyAppSecret' + '&scope=Policy.Read.All,Policy.ReadWrite.MobilityManagement '
$token = (Invoke-RestMethod -Method Post -Uri https://login.microsoftonline.com/common/oauth2/token -Body $TokenBody).access_token
#Blocked here :
"error": "interaction_required",
"error_description": "AADSTS50076: Due to a configuration change made by your administrator, or because you moved to a new location, you must use multi-factor authentication to access
$method = "PUT"
$uri = "https://graph.microsoft.com/beta/policies/deviceRegistrationPolicy"
$body = '{
"userDeviceQuota": 1,
"multiFactorAuthConfiguration": "0",
"azureADRegistration": {
"appliesTo": "1",
"isAdminConfigurable": false,
"allowedUsers": [],
"allowedGroups": []
}
}'
Can someone please help me to understand what I'm missing?
PS : I'm GlobalAdmin on the tenant! Best regards,
2 answers
Sort by: Most helpful
-
-
Jean-Valentin 6 Reputation points
2024-03-04T15:30:51.8433333+00:00 Hi Vasil Michev, thank you for taking time to answer me.
I was off for one week, sorry for the delay.
My purpose is to have an automated script able to retreive the bitlocker keys from computers to identify if there is some missing.
Of course if I do this with my Global Admin account, it works :
I can use on a elvated powershell :
Connect-MgGraph -Scopes BitlockerKey.Read.All -NoWelcome
It opens a browser to authenticate my admin account. Once done I can run :
Get-MgInformationProtectionBitlockerRecoveryKey –All | select Id,CreatedDateTime,DeviceId,@{n="Key";e={(Get-MgInformationProtectionBitlockerRecoveryKey -BitlockerRecoveryKeyId $_.Id -Property key).key}},VolumeType | export-csv c:\tmp\bitlocker.csv
But reading Microsoft documentation : https://learn.microsoft.com/en-us/graph/api/bitlocker-list-recoverykeys?view=graph-rest-1.0&tabs=powershell
It's well written Application rights for bitlocker are not supported, only delegated.
So I'm a bit confused, and don't understand how I can automated my script. I can't understand the point to use an app if I need to grant the access with my global admin account.
Because for example :
OK also with this code but need my approval and need to enable Microsoft Graph command line tools
$clientAppId = "MyAppID"
$resourceAppId = "00000003-0000-0000-c000-000000000000" # Microsoft Graph API
$permissions = @("BitlockerKey.Read.All", "Device.Read.All", "User.Read.All")
$userUpnOrId = "MyadmAccount@contoso.com"
Connect-MgGraph -Scopes ("User.ReadBasic.All Application.ReadWrite.All " + "DelegatedPermissionGrant.ReadWrite.All " + "AppRoleAssignment.ReadWrite.All")
$clientSp = Get-MgServicePrincipal -Filter "appId eq '$($clientAppId)'"
if (-not $clientSp) {
$clientSp = New-MgServicePrincipal -AppId $clientAppId
}
$user = Get-MgUser -UserId $userUpnOrId
$resourceSp = Get-MgServicePrincipal -Filter "appId eq '$($resourceAppId)'"
$scopeToGrant = $permissions -join " "
$grant = New-MgOauth2PermissionGrant -ResourceId $resourceSp.Id -Scope $scopeToGrant -ClientId $clientSp.Id -ConsentType "Principal" -PrincipalId $user.Id
if ($clientSp.AppRoles | ? { $_.AllowedMemberTypes -contains "User" }) {
Write-Warning ("A default app role assignment cannot be created because the client application exposes user-assignable app roles. You must assign the user a specific app role for the app to be listedin the user's My Apps access panel.")
} else {
# The app role ID 00000000-0000-0000-0000-000000000000 is the default app role # indicating that the app is assigned to the user, but not for any specific # app role. $assignment = New-MgServicePrincipalAppRoleAssignedTo -ServicePrincipalId $clientSp.Id -ResourceId $clientSp.Id -PrincipalId $user.Id -AppRoleId "00000000-0000-0000-0000-000000000000" -ErrorAction SilentlyContinue
}
I hope I'm clear enough.
Regards