Audit Logs Application URI Added
Query
AuditLogs
| where Category == "ApplicationManagement" and AADOperationType == "Update" //and OperationName == "Update Application" and Result == "success"
| mv-expand modifiedProperty = TargetResources[0]["modifiedProperties"]
| extend ModifiedProperty = tostring(modifiedProperty["displayName"])
| where ModifiedProperty in ("AppIdentifierUri", "AppAddress")
| extend
NewAddresses = iff(ModifiedProperty == "AppIdentifierUri", todynamic(tostring(modifiedProperty["newValue"])), extract_all(@'\"Address\"\:\"([^"]+)\"', tostring(modifiedProperty["newValue"]))),
OldAddresses = iff(ModifiedProperty == "AppIdentifierUri", todynamic(tostring(modifiedProperty["oldValue"])), extract_all(@'\"Address\"\:\"([^"]+)\"', tostring(modifiedProperty["oldValue"])))
| where isnotempty(NewAddresses)
| extend AddedAddresses = set_difference(NewAddresses, OldAddresses)
| where array_length(AddedAddresses) > 0
| extend AppDisplayName = tostring(TargetResources[0]["displayName"])
| summarize
TimeGenerated = min(TimeGenerated),
AddedAddresses = array_sort_asc(make_set(AddedAddresses)),
NewAddresses = array_sort_asc(make_set(NewAddresses)),
OldAddresses = array_sort_asc(make_set(OldAddresses)),
OperationNames = array_sort_asc(make_set(OperationName)),
TargetResources = make_bag(bag_pack(Id, TargetResources)),
OperationIds = make_list(Id),
take_any(*)
by CorrelationId, AppDisplayName, Result
| extend
Initiator = iif(isnotempty(InitiatedBy["app"]), tostring(InitiatedBy["app"]["displayName"]), tostring(InitiatedBy["user"]["userPrincipalName"])),
InitiatorId = iif(isnotempty(InitiatedBy["app"]), tostring(InitiatedBy["app"]["servicePrincipalId"]), tostring(InitiatedBy["user"]["id"])),
IPAddress = tostring(InitiatedBy[tostring(bag_keys(InitiatedBy)[0])]["ipAddress"])
| mv-expand AddedAddress = AddedAddresses to typeof(string)
| project
TimeGenerated,
LoggedByService,
Category,
AADOperationType,
Initiator = coalesce(Initiator, Identity),
IPAddress,
OperationNames,
Result,
AppDisplayName,
AddedAddress,
AddedAddresses,
OldAddresses,
NewAddresses,
AdditionalDetails,
InitiatedBy,
InitiatorId,
TargetResources,
OperationIds,
CorrelationIdExplanation
This KQL query is designed to analyze audit logs related to application management updates in Azure Active Directory (AAD). Here's a simplified breakdown of what the query does:
-
Filter Logs: It starts by filtering the
AuditLogstable to include only entries where the category is "ApplicationManagement" and the operation type is "Update". -
Expand Modified Properties: It expands the
modifiedPropertiesof the first target resource to examine changes made to specific properties. -
Identify Relevant Changes: The query focuses on changes to the "AppIdentifierUri" and "AppAddress" properties.
-
Extract New and Old Values: It extracts the new and old values of these properties, specifically looking for changes in addresses.
-
Find Added Addresses: It identifies any new addresses that were added by comparing the new and old values.
-
Filter for Changes: It filters the results to include only those entries where new addresses were added.
-
Summarize Data: The query summarizes the data by correlation ID, application display name, and result, collecting various details such as the earliest time the change was generated, the added, new, and old addresses, operation names, and target resources.
-
Identify Initiator: It determines who initiated the change, whether it was an application or a user, and captures their ID and IP address.
-
Expand and Project Results: Finally, it expands the list of added addresses and projects a set of relevant columns, including the time the log was generated, the service that logged it, the category, operation type, initiator details, and the addresses involved in the change.
Overall, this query helps identify and analyze updates to application identifiers and addresses, highlighting any new addresses added during these updates.
Details

Jose Sebastián Canós
Released: August 8, 2025
Tables
Keywords
Operators