-
Notifications
You must be signed in to change notification settings - Fork 4.1k
Description
Get-AzADApplication fails with an ArgumentException when the tenant contains app registrations of type
#microsoft.graph.agentIdentityBlueprint (auto-created by Azure AI Foundry / Azure Machine Learning). These apps return @odata.type
at the root level of the Graph API response, which causes a duplicate key collision during deserialization.
The issue started on 2026-03-13 without any changes to the runbook, automation account, or the app registrations themselves. It
was working fine on 2026-03-12. This points to a server-side change (either in the Azure Automation 7.2 runtime sandbox or the
Graph API response format).
Steps to reproduce
- Have an Azure tenant with Azure AI Foundry Agent projects (these auto-create agentIdentityBlueprint app registrations)
- Run Get-AzADApplication using Az.Resources 6.2.0 (bundled with Az 8.3.0 in Azure Automation PowerShell 7.2 runtime)
Connect-AzAccount -Identity
$apps = Get-AzADApplication # <-- crashes here
Error output
Get-AzADApplication_List: C:\AzAt\Modules\8.3.0\Az.Resources\6.2.0\MSGraph.Autorest\custom\Get-AzADApplication.ps1:208
Line |
208 | Az.MSGraph.internal\Get-AzADApplication @PSBoundParameters
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| An item with the same key has already been added. Key: @odata.type
Full exception details:
=== ERROR DETAILS ===
Message: An item with the same key has already been added. Key: @odata.type
Type: System.ArgumentException
Script Stack:
at Get-AzADApplication, C:\AzAt\Modules\8.3.0\Az.Resources\6.2.0\MSGraph.Autorest\internal\ProxyCmdletDefinitions.ps1:
line 1065
at Get-AzADApplication, C:\AzAt\Modules\8.3.0\Az.Resources\6.2.0\MSGraph.Autorest\custom\Get-AzADApplication.ps1: line
208
at Get-AzADApplication, C:\AzAt\Modules\8.3.0\Az.Resources\6.2.0\MSGraph.Autorest\exports\ProxyCmdletDefinitions.ps1:
line 2054
Root cause analysis
We identified specific app registrations causing the crash. They are all of type #microsoft.graph.agentIdentityBlueprint,
auto-created by the Azure Machine Learning service principal (0736f41a-0425-4b46-bdb5-1563eff02385) when Azure AI Foundry Agent
projects are created.
Key difference between normal and broken apps:
Normal app registration Graph API response:
{
"@odata.context": "https://graph.microsoft.com/v1.0/$metadata#applications/$entity",
"displayName": "my-normal-app",
...
}
agentIdentityBlueprint app registration Graph API response:
{
"@odata.context": "https://graph.microsoft.com/v1.0/$metadata#applications/$entity",
"@odata.type": "#microsoft.graph.agentIdentityBlueprint",
"displayName": "my-agentIdentityBlueprint-app-...-AgentIdentityBlueprint",
...
}
The @odata.type field at the root level causes Az.Resources' deserialization logic to attempt adding the key twice to an internal
dictionary — once from the JSON response itself, and once as an internally-generated type discriminator — resulting in the
ArgumentException.
Additional notes:
• These agentIdentityBlueprint apps are not visible in the Entra ID > App registrations portal UI — they can only be seen via
the Graph API
• They have no secrets or certificates (passwordCredentials and keyCredentials are empty)
• There is no way to filter them out using Get-AzADApplication parameters since @odata.type is not a filterable property and the
crash occurs during deserialization before any client-side filtering
• Upgrading Az.Resources in Azure Automation is not feasible (module import fails — see #21647)
Environment data
Runtime: Azure Automation Account, PowerShell 7.2
Az: 8.3.0 (bundled)
Az.Accounts: 2.8.0 (bundled)
Az.Resources: 6.2.0 (bundled)
Location: East US
Workaround
Replace Get-AzADApplication with direct Microsoft Graph API calls using Invoke-RestMethod, which does not suffer from the
deserialization issue:
$token = (Get-AzAccessToken -ResourceTypeName MSGraph).Token
$headers = @{ Authorization = "Bearer $token" }
$apps = @()
$uri = "https://graph.microsoft.com/v1.0/applications?`$select=displayName,appId,passwordCredentials&`$top=999"
do {
$r = Invoke-RestMethod -Uri $uri -Headers $headers -Method Get
$apps += $r.value
$uri = $r.'@odata.nextLink'
} while ($uri)