Table of Contents
Use Email to Circulate Details of Role Assignments and Removals
Writing about the arrival of the Teams external collaboration role, I made the point that it’s a good idea to conduct a periodic review of role assignments within Microsoft 365 tenants to make sure that people don’t cling onto roles when those roles are no longer required. Well, it’s also a good idea to keep an eye on role assignments (additions and removals) as they occur.
Reviewing a complete Entra ID role assignment report is one way to find unnecessary roles assignments, but busy tenant administrators might not have the time to check each assignment. Dealing with just the assignment changes that occur within the last week is a more achievable task. Fortunately, the work involved in generating such a report and delivering it via email isn’t very difficult.
Accessing Role Assignment Audit Records
Entra ID captures audit records every time an administrator creates a new role assignment or removes an existing role assignment. The audit records are available through the Entra admin center or programmatically through a Graph API. The audit records also flow through to the unified audit log, where the data is accessible through the Purview audit solution, the Search-UnifiedAuditLog cmdlet, and the AuditLogQuery Graph API. Microsoft is dealing with some known issues in the AuditLogQuery API at present, so that option is not recommended.
I like the idea of automating tasks that should be performed regularly and prefer to use Azure Automation to run procedures on a dependable scheduled basis. To keep things simple, I decided to avoid using the Search-UnifiedAuditLog cmdlet and retrieve the audit data from Entra ID instead. This approach allows me to use the Microsoft Graph PowerShell SDK for everything and avoid any possibility of assembly clashes.
After connecting to the Graph with the AuditLog.Read.All scope, this command finds all role assignment addition and removal records for the last week:
# Retrieve role assignment events from the last week
$StartDate = (Get-Date).AddDays(-7).toString('yyyy-MM-dd')
Write-Output "Checking for role assignments in the last week since $StartDate..."
[array]$Records = Get-MgAuditLogDirectoryAudit -All -Filter `
"(activityDisplayName eq 'Add member to role' or activityDisplayName eq 'Remove member from role') and ActivityDateTime gt $StartDate"
An Entra ID audit record looks like this:
ActivityDateTime : 14/01/2026 14:42:43
ActivityDisplayName : Add member to role
AdditionalDetails : {}
Category : RoleManagement
CorrelationId : 6f5d5a61-89af-46f2-af4c-b03e08fbb4c2
Id : Directory_6f5d5a61-89af-46f2-af4c-b03e08fbb4c2_AH36X_123650044
InitiatedBy : Microsoft.Graph.PowerShell.Models.MicrosoftGraphAuditActivityInitiator
LoggedByService : Core Directory
OperationType : Assign
Result : success
ResultReason :
TargetResources : {4adf6057-95da-430a-8757-6a58c85e13d4, 53add08e-5b0c-4276-a582-9ce02fb6c947}
AdditionalProperties : {}
Like with any audit record, some processing is required to extract the interesting information. For example, the targetResources property holds details of the user account and role involved in the assignment:
Id Type UserPrincipalName -- ---- ----------------- 4adf6057-95da-430a-8757-6a58c85e13d4 User Michelle.Dubois@office365itpros.com 53add08e-5b0c-4276-a582-9ce02fb6c947 Role
The InitiatedBy property holds details of the process or user responsible for initiating the change. If you use Entra Privileged Identity Management, many of the changes are made by an enterprise app called MS-PIM (service principal ddfe4cbb-47fa-4aa0-95c0-430644c7dc5d).
Highlighting Critical Role Assignments
After extracting information from the audit records, you can format the data in whatever way makes sense to highlight it to administrators. For example, an assignment of the Global Reader role is probably not very exciting and worth much attention, but the assignment of a workload administrative role like SharePoint administrator or Teams administrator is a much more important event. Other critical roles include Privileged Role administrator and security administrator. To highlight assignments for critical roles (defined in an array), the processing adds a suitable icon to include in the output.
Bringing everything together, we can generate an Excel worksheet (if the ImportExcel module is available) or CSV file and attach it to an email sent to interested parties. By adding the runbook to a suitable Azure Automation schedule, we can assure that the weekly report is delivered to mailboxes (Figure 1) at a suitable time (9AM on Monday seems good).

Access to the Script to Send the Weekly Role Assignment Report
If you’d like a copy of the complete script, you can download it from the Office 365 GitHub repository. The code runs interactively and as an Azure Automation runbook. If you run the script interactively, the code sends the message from the mailbox of the signed-in account. Make sure that you update the code with a suitable destination address for your tenant.
PS. I am scheduled to speak about using Azure Automation with Microsoft 365 at the Microsoft 365 Community Conference in Orlando in April. If you’d like to come along, you can use the code REDMOND150 to get a $150 discount.
Need help to write and manage PowerShell scripts for Microsoft 365, including Azure Automation runbooks? Get a copy of the Automating Microsoft 365 with PowerShell eBook, available standalone or as part of the Office 365 for IT Pros eBook bundle.