Audit Logs Changesto Application Ownership
Query
AuditLogs
| where LoggedByService == "Core Directory" and Category == "ApplicationManagement" and OperationName has "owner"
| mv-apply modifiedProperty = TargetResources[0]["modifiedProperties"] on (
summarize modifiedProperties = make_bag(bag_pack(tostring(modifiedProperty["displayName"]), bag_pack("oldValue", trim(@'[\"\s]+', tostring(modifiedProperty["oldValue"])), "newValue", trim(@'[\"\s]+', tostring(modifiedProperty["newValue"])))))
)
| extend
OwnerId = TargetResources[0]["id"],
Owner = TargetResources[0]["userPrincipalName"],
AppDisplayName = tostring(modifiedProperties[case(OperationName has "application", "Application.DisplayName", OperationName has "service principal", "ServicePrincipal.DisplayName", "")][case(AADOperationType == "Assign", "newValue", AADOperationType == "Unassign", "oldValue", "")]),
AppId = tostring(modifiedProperties[case(OperationName has "application", "Application.AppId", OperationName has "service principal", "ServicePrincipal.AppId", "")]["newValue"]),
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"])
| project
TimeGenerated,
LoggedByService,
Category,
AADOperationType,
Initiator,
IPAddress,
OperationName,
Result,
Owner,
AppDisplayName,
InitiatedBy,
AdditionalDetails,
TargetResources,
InitiatorId,
OwnerId,
AppId,
CorrelationIdExplanation
This KQL query is designed to analyze audit logs related to changes in application ownership within a directory service. Here's a simplified breakdown of what the query does:
-
Filter Logs: It starts by filtering audit logs to include only those entries where the service that logged the event is "Core Directory," the category is "ApplicationManagement," and the operation name contains the word "owner."
-
Extract and Summarize Changes: For each log entry, it examines the modified properties of the target resources. It creates a summary of these changes, focusing on the display name, old value, and new value of the modified properties.
-
Extend Information: The query then extracts additional details from the logs:
- OwnerId and Owner: Identifies the ID and user principal name of the owner.
- AppDisplayName and AppId: Determines the display name and ID of the application or service principal involved, based on the operation type (assign or unassign).
- Initiator and InitiatorId: Identifies who initiated the change, whether it's an application or a user, and captures their display name and ID.
- IPAddress: Captures the IP address from which the change was initiated.
-
Project Relevant Fields: Finally, it selects and displays a set of relevant fields from the logs, including:
- TimeGenerated: When the log entry was created.
- LoggedByService, Category, AADOperationType, OperationName, Result: Basic details about the log entry.
- Initiator, IPAddress, Owner, AppDisplayName: Information about the change and the entities involved.
- AdditionalDetails, TargetResources, InitiatedBy, InitiatorId, OwnerId, AppId, CorrelationId: Additional context and identifiers related to the log entry.
Overall, this query is used to track and analyze changes in application ownership, providing insights into who made the changes, what was changed, and when it happened.
Details

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