Track Manager Changes in Microsoft 365 Using Graph PowerShell

When a user’s reporting manager is updated in Microsoft 365—whether as part of onboarding, team restructuring, or leadership changes—it’s important for admins to track and audit these changes for accountability and compliance.

In this article, we’ll walk you through a Graph PowerShell script that queries Microsoft 365 audit logs and retrieves all "Set user manager" actions performed by admins, including who made the change, when, and who the new manager is.


The Script

# Connect to Microsoft Graph with the necessary scopes
Connect-MgGraph -Scopes "AuditLog.Read.All", "User.Read.All", "Directory.Read.All"
                                
# Define the time window (last 30 days max)
$startDate = (Get-Date).AddDays(-30).ToString("yyyy-MM-ddTHH:mm:ssZ")
                                
# Query 'Set user manager' actions from UserManagement category
$managerChanges = Get-MgAuditLogDirectoryAudit -Filter "activityDisplayName eq 'Set user manager' and category eq 'UserManagement' and activityDateTime ge $startDate" -All
                                
# Process and display results
$results = foreach ($log in $managerChanges) {
    # Attempt to get the new manager's object ID from the audit log
    $managerIdRaw = $log.TargetResources.ModifiedProperties | Where-Object { $_.DisplayName -eq 'manager' } | Select-Object -ExpandProperty NewValue -ErrorAction SilentlyContinue
                                    
    # Sanitize value (remove extra characters like quotes/braces)
    $managerId = $managerIdRaw -replace '[^\w\-@.]', ''
                                    
    # Resolve manager UPN (if possible)
    $newManagerUPN = $null
        try {
            $managerObj = Get-MgUser -UserId $managerId -Property UserPrincipalName -ErrorAction Stop
            $newManagerUPN = $managerObj.UserPrincipalName
        } catch {
            $newManagerUPN = $managerId # Fallback to object ID if UPN can't be resolved
        }
                                    
    [PSCustomObject]@{
        "Performed Time"     = ($log.ActivityDateTime).ToLocalTime()
        "Performed On"       = $log.TargetResources[0].UserPrincipalName
        "Performed By (UPN)" = $log.InitiatedBy.User.UserPrincipalName
        "Result"             = if ($log.Result -eq "success") { "Success" } else { "Failure" }
    }
}
                                
# Display in table format
$results | Format-Table -AutoSize
                            

How the Script Works

Here’s a breakdown of what the script does:

  1. Connects to Microsoft Graph with the required permissions:
    • AuditLog.Read.All
    • User.Read.All
    • Directory.Read.All
  2. Queries audit logs using:
    • activityDisplayName eq 'Set user manager'
    • category eq 'UserManagement'
    • Logs from the past 30 days (the max audit retention via Graph).
  3. Extracts relevant info: the log details to display:
    • Performed Time: When the manager was changed.
    • Performed On: The user whose manager was updated.
    • Performed By: The admin who made the change.
    • New Manager: Extracted from the ModifiedProperties array and resolved to UPN.
  4. Cleans up the manager’s ID and attempts to resolve it to a UPN for clarity.
  5. Displays results in a neatly formatted table.

Further Enhancements

You can enhance this script further based on your organization’s needs:

  • Export to CSV for Reporting:
  • $results | Export-Csv -Path "ManagerChangesReport.csv" -NoTypeInformation
  • Accept Custom Date Ranges: Add parameters to input custom start and end dates instead of defaulting to 30 days.
  • Schedule for Continuous Monitoring: Schedule the script using Task Scheduler or Azure Automation to run weekly and email results.
  • Filter by Admin: Narrow down results by a specific admin UPN:
  • $results | Where-Object { $_."Performed By (UPN)" -like "*admin.contoso.com" }

Use Cases

  • Onboarding / Offboarding Audits: Verify when managers are assigned or updated during user lifecycle events.
  • Hierarchy Verification:Ensure changes in reporting structure are properly tracked.
  • Compliance Auditing: Maintain accountability for role changes in leadership structures.
  • HR Sync Validation: Cross-check if HR-driven manager updates are reflected in Azure AD.

Possible Errors & Solutions

Error Cause Solution
Access Denied Missing Graph API permissions Connect with: -Scopes "AuditLog.Read.All", "User.Read.All", "Directory.Read.All"
ModifiedProperties is null Audit log doesn't include expected fields May occur in older logs or incomplete operations
Manager UPN is blank UPN lookup failed due to object not being a user Check if the manager is a group or contact; fallback to object ID
CommandNotFoundException Microsoft Graph module not installed Run: Install-Module Microsoft.Graph -Scope CurrentUser

Conclusion

Tracking manager changes is more than just operational hygiene—it’s essential for security, visibility, and business continuity. With this Graph PowerShell script, you can now audit all manager updates across your Microsoft 365 tenant and know who made the change, when, and to whom.

Use this script as part of your regular audit toolkit or integrate it into automated reporting pipelines for maximum efficiency.


Graph PowerShell Explorer Widget

20 Graph PowerShell cmdlets with easily accessible "working" examples.


Permission Required

Example:


                


                


                

© m365corner.com. All Rights Reserved. Design by HTML Codex