|
| 1 | +--- |
| 2 | +title: Entra ID Graph API retirement |
| 3 | +description: Learn how to mitigate the retirement of the Entra ID Graph API. |
| 4 | +author: sethmanheim |
| 5 | +ms.author: sethm |
| 6 | +ms.topic: conceptual |
| 7 | +ms.date: 02/05/2025 |
| 8 | +ms.reviewer: rtiberiu |
| 9 | + |
| 10 | +--- |
| 11 | + |
| 12 | +# Microsoft Entra ID Graph API retirement |
| 13 | + |
| 14 | +The Microsoft Entra ID (formerly Azure Active Directory or Azure AD) [Graph API service is being retired](https://techcommunity.microsoft.com/blog/microsoft-entra-blog/important-update-azure-ad-graph-api-retirement/4090534). This retirement is part of a broader effort to streamline the Microsoft Entra ID platform and improve the Microsoft Entra ID developer experience. |
| 15 | + |
| 16 | +## Mitigation steps |
| 17 | + |
| 18 | +The Graph API retirement affects all Azure Stack Hub customers, and requires you to run the script included in this article for all affected applications. If you have applications that need continued access to the Graph APIs, the script configures these applications for an extension that allows these specific applications to continue calling the legacy Graph API until June 2025. |
| 19 | + |
| 20 | +The script provided in this article sets a flag for each application to configure the Graph API extension for your connected Azure Stack environments. |
| 21 | + |
| 22 | +To ensure that your connected Azure Stack environments continue functioning through the June cutoff date and beyond, you should run this script by the end of February 2025. |
| 23 | + |
| 24 | +## Run the script |
| 25 | + |
| 26 | +Run the following script in your Azure Stack Hub environment to configure the Graph API extension. You can run the script after your environment is deployed. The script interacts with Azure, so you don't need to run it on a specific machine. However, you need to have administrator access to run the script, and you must run it in each of your directory tenants. |
| 27 | + |
| 28 | +Make sure to run the following script with administrator privileges: |
| 29 | + |
| 30 | +```powershell |
| 31 | +# Install the graph modules if necessary |
| 32 | +#Install-Module Microsoft.Graph.Authentication |
| 33 | +#Install-Module Microsoft.Graph.Applications |
| 34 | + |
| 35 | +$ErrorActionPreference='Stop' |
| 36 | +Import-Module Microsoft.Graph.Authentication |
| 37 | +Import-Module Microsoft.Graph.Applications |
| 38 | + |
| 39 | +# Repeat this flow for each of your target directory tenants |
| 40 | +$tenantId = 'MyTenantId' |
| 41 | + |
| 42 | +# Sign-in with admin permissions to read and write all application objects |
| 43 | +Connect-MgGraph -TenantId $tenantId -Scopes Application.ReadWrite.All |
| 44 | + |
| 45 | +# Retrieve all applications in the current directory |
| 46 | +Write-Host "Looking-up all applications in directory '$tenantId'..." |
| 47 | +$applications = Get-MgApplication -All -Property id, displayName, appId, identifierUris, requiredResourceAccess, authenticationBehaviors |
| 48 | +Write-Host "Found '$($applications.Count)' total applications in directory '$tenantId'" |
| 49 | + |
| 50 | +# Find all the unique deployment guids, each one representing an Azure Stack deployment in the current directory |
| 51 | +$deploymentGuids = $applications.IdentifierUris | |
| 52 | + Where-Object { $_ -like 'https://management.*' -or $_ -like 'https://adminmanagement.*' } | |
| 53 | + ForEach-Object { "$_".Split('/')[3] } | |
| 54 | + Select-Object -Unique |
| 55 | +Write-Host "Found '$($deploymentGuids.Count)' total Azure Stack deployments in directory '$tenantId'" |
| 56 | + |
| 57 | +# Find all the Azure Stack application objects for each deployment |
| 58 | +$azureStackApplications = @() |
| 59 | +foreach ($application in $applications) |
| 60 | +{ |
| 61 | + foreach ($deploymentGuid in $deploymentGuids) |
| 62 | + { |
| 63 | + if (($application.IdentifierUris -join '') -like "*$deploymentGuid*") |
| 64 | + { |
| 65 | + $azureStackApplications += $application |
| 66 | + } |
| 67 | + } |
| 68 | +} |
| 69 | + |
| 70 | +# Find which Azure Stack applications require access to Legacy Graph Service |
| 71 | +$azureStackLegacyGraphApplications = $azureStackApplications | |
| 72 | + Where-Object { $_.RequiredResourceAccess.ResourceAppId -contains '00000002-0000-0000-c000-000000000000' } |
| 73 | + |
| 74 | +# Find which of those applications need to have their authentication behaviors patched to allow access to Legacy Graph |
| 75 | +$azureStackLegacyGraphApplicationsToUpdate = $azureStackLegacyGraphApplications | |
| 76 | + Where-Object { -not ($ab = $_.AdditionalProperties.authenticationBehaviors) -or -not $ab.ContainsKey(($key='blockAzureADGraphAccess')) -or $ab[$key] } |
| 77 | + |
| 78 | +# Update the applications which require their authentication behaviors patched to allow access to Legacy Graph |
| 79 | +Write-Host "Found '$($azureStackLegacyGraphApplicationsToUpdate.Count)' total Azure Stack applications which need permission to continue calling Legacy Microsoft Graph Service" |
| 80 | +$count = 0 |
| 81 | +foreach ($application in $azureStackLegacyGraphApplicationsToUpdate) |
| 82 | +{ |
| 83 | + $count++ |
| 84 | + Write-Host "$count/$($azureStackLegacyGraphApplicationsToUpdate.Count) - Updating application '$($application.DisplayName)' (appId=$($application.AppId)) (id=$($application.Id))" |
| 85 | + Update-MgApplication -ApplicationId $application.Id -BodyParameter @{ |
| 86 | + authenticationBehaviors = @{ blockAzureADGraphAccess = $false } |
| 87 | + } |
| 88 | +} |
| 89 | +``` |
| 90 | + |
| 91 | +The script displays the following sample output: |
| 92 | + |
| 93 | +```output |
| 94 | +Looking-up all applications in directory '<ID>'... |
| 95 | +Found '3164' total applications in directory '<ID>' |
| 96 | +Found '102' total Azure Stack deployments in directory '<app ID>' |
| 97 | +Found '14' total Azure Stack applications which need permission to continue calling Legacy Microsoft Graph Service |
| 98 | +1/14 - Updating application 'Azure Stack - AKS' (appId=<app ID>) (id=<ID>) |
| 99 | +2/14 - Updating application 'Azure Stack - Hubs' (appId=<app ID>) (id=<ID>) |
| 100 | +3/14 - Updating application 'Azure Stack - Portal Administration' (appId=<app ID>) (id=<app>) |
| 101 | +4/14 - Updating application 'Azure Stack - RBAC Administration' (appId=<app ID>) (id=ID) |
| 102 | +5/14 - Updating application 'Azure Stack - Container Registry' (appId=<app ID>) (id=ID) |
| 103 | +6/14 - Updating application 'Azure Stack - RBAC' (appId=<app ID>) (id=ID) |
| 104 | +7/14 - Updating application 'Azure Stack - Hubs Administration' (appId=<app ID>) (id=ID) |
| 105 | +8/14 - Updating application 'Azure Stack - Deployment Provider' (appId=<app ID>) (id=ID) |
| 106 | +9/14 - Updating application 'Azure Stack - Deployment' (appId=<app ID>) (id=ID) |
| 107 | +10/14 - Updating application 'Azure Stack - KeyVault' (appId=<app ID>) (id=ID) |
| 108 | +11/14 - Updating application 'Azure Stack' (appId=<app ID>) (id=ID) |
| 109 | +12/14 - Updating application 'Azure Stack - Administration' (appId=<app ID>) (id=ID) |
| 110 | +13/14 - Updating application 'Azure Stack - Policy Administration' (appId=<app ID>) (id=ID) |
| 111 | +14/14 - Updating application 'Azure Stack - Policy' (appId=<app ID>) (id=ID) |
| 112 | +``` |
| 113 | + |
| 114 | +Run the script a second time to verify that all applications were updated. The script should return the following output if all applications were successfully updated: |
| 115 | + |
| 116 | +```output |
| 117 | +Looking-up all applications in directory '104edf09-7fc1-459f-8c4e-b062db480b90'... |
| 118 | +Found '3164' total applications in directory '104edf09-7fc1-459f-8c4e-b062db480b90' |
| 119 | +Found '102' total Azure Stack deployments in directory '104edf09-7fc1-459f-8c4e-b062db480b90' |
| 120 | +Found '0' total Azure Stack applications which need permission to continue calling Legacy Microsoft Graph Service |
| 121 | +``` |
| 122 | + |
| 123 | +## Next steps |
| 124 | + |
| 125 | +[Azure Stack Hub release notes](release-notes.md) |
0 commit comments