Query Details

Summary Of Privileged Operations By Directory Role Member

Query

// Query based on Microsoft TechCommunity blog post "Easily Manage Privileged Role Assignments in Microsoft Entra ID Using Audit Logs"
// Source: https://techcommunity.microsoft.com/t5/microsoft-entra-blog/easily-manage-privileged-role-assignments-in-microsoft-entra-id/ba-p/4013854
// List of operations (sorted by count) performed by privileged users (and all directory roles) in the last 14 days and showing related Enterprise Access Model Tiering Level and built-in classification by Microsoft (isPrivileged)

let Lookback = 14d;
let PrivilegedRoles = externaldata(RoleName: string, RoleId: string, isPrivileged: bool, Classification: dynamic)["https://raw.githubusercontent.com/Cloud-Architekt/AzurePrivilegedIAM/main/Classification/Classification_EntraIdDirectoryRoles.json"] with(format='multijson')
| where Classification.EAMTierLevelName != "Unclassified"
| extend EAMTierLevelName = Classification.EAMTierLevelName
| project RoleName, isPrivileged, EAMTierLevelName;
AuditLogs 
| where TimeGenerated > ago(Lookback) 
| extend ActorName = iif( 
                         isnotempty(tostring(InitiatedBy["user"])),  
                         tostring(InitiatedBy["user"]["userPrincipalName"]), 
                         tostring(InitiatedBy["app"]["displayName"]) 
                     ) 
| extend ActorID = iif( 
                       isnotempty(tostring(InitiatedBy["user"])),  
                       tostring(InitiatedBy["user"]["id"]), 
                       tostring(InitiatedBy["app"]["appId"]) 
                   ) 
| where isnotempty(ActorName) 
| join kind=inner (IdentityInfo 
    | where TimeGenerated > ago(Lookback) 
    | mv-expand AssignedRoles
    | extend RoleName = tostring(AssignedRoles)
    | join kind=inner ( PrivilegedRoles) on RoleName
    | summarize EAMTierLevelName = make_set(EAMTierLevelName), isPrivileged = make_set(isPrivileged), AssignedRoles = make_set(AssignedRoles) by AccountObjectId
    | extend isPrivileged = iff((isPrivileged contains "true"), true, false)
    ) on $left.ActorID == $right.AccountObjectId 
| where AssignedRoles has_any (PrivilegedRoles) 
| summarize Operations = make_set(OperationName) by ActorName, ActorID, tostring(AssignedRoles), tostring(isPrivileged), tostring(EAMTierLevelName)
| extend OperationsCount = array_length(Operations) 
| project ActorName, ActorID, EAMTierLevelName, isPrivileged, AssignedRoles, Operations, OperationsCount
| sort by OperationsCount desc 

Explanation

This query looks at the operations performed by privileged users and all directory roles in the last 14 days. It shows the Enterprise Access Model Tiering Level and built-in classification by Microsoft for these roles. It identifies the users, their roles, and the number of operations they have performed, sorting them by the count of operations in descending order.

Details

Thomas Naunheim profile picture

Thomas Naunheim

Released: March 24, 2024

Tables

AuditLogsIdentityInfoPrivilegedRoles

Keywords

PrivilegedRoles,AuditLogs,TimeGenerated,ActorName,InitiatedBy,IdentityInfo,AssignedRoles,AccountObjectId,OperationName,OperationsCount,EAMTierLevelName.

Operators

extendprojectwhereisnotemptyiifjoinmv-expandsummarizemake_setbyiffcontainshas_anyarray_lengthsort

Actions