Getting More Information About Administrative Units with PowerShell
Microsoft’s recent announcement of the preview of restricted administrative units made me think that it would be a good idea to be able to report details of administrative units and their membership. The Microsoft Entra ID admin center reveals this information, and it’s easy to review the properties of an individual administrative unit, but it’s a lot harder to get a concise overview of all the administrative units in a tenant.
If your tenant uses administrative units, it’s important that you keep tabs on their use. Microsoft is obviously paying more attention to these objects because they go a long way to solving the problem of scoping within the directory. Purview solutions like Data Loss Prevention (DLP) and Data lifecycle management (retention labels and policies) support the configuration of policies scoped to administrative units. I expect other parts of the Microsoft 365 ecosystem to follow a similar approach over time.
Microsoft Graph PowerShell SDK V2
This article describes how to use cmdlets from the Microsoft Graph PowerShell SDK to retrieve the information and create a report. Microsoft released V2 of the SDK on July 4, 2023. The obvious difference between V1 and V2 of the SDK is that cmdlets interacting with the production Graph endpoint (V1.0) follow a *-Mg* naming scheme while their beta counterparts have *-MgBeta* names.
For example, the cmdlets to retrieve Entra ID (Azure AD) user accounts are Get-MgUser and Get-MgBetaUser, respectively. The change in cmdlet naming means that developers should review and test any scripts written using V1 of the SDK to ensure that their code runs with V2.
Microsoft Graph PowerShell SDK V2 divides its cmdlets into two sub-modules, and you must install both to have access to the beta cmdlets. On the upside, the division into separate modules means that it’s easier and faster to load the SDK in environments like Azure Automation. Another important change for Azure Automation is formal support for managed identities. Workarounds have existed in the past, like getting an access token from the Azure Automation account and using the token to authenticate, but now you can simply do:
Connect-MgGraph -Identity
If you use the SDK with Azure Automation, make sure to import the beta modules holding any cmdlets used in runbooks.
The Microsoft 365 Kill Chain and Attack Path Management
An effective cybersecurity strategy requires a clear and comprehensive understanding of how attacks unfold. Read this whitepaper to get the expert insight you need to defend your organization!
Updating the Microsoft Graph PowerShell SDK
Nine days after releasing SDK V2.0, Microsoft rushed out V2.1 (July 13, 2023) to fix some issues. For instance, the Get-MgServicePrincipal cmdlet stubbornly refused to display any parameters! Normally, Microsoft generates a new version of the SDK monthly. However, in the early days of V2, it might be wise to keep an eye on the PowerShell Gallery to make sure that you use the latest and most stable code.
The script described in this article updates the V1.0 and beta SDK modules installed in Azure Automation accounts to the latest version. The script from this article takes care of SDK module update (and other modules) on a PC.
Reporting Administrative Units
Getting back to administrative units, the basic processing steps I used to create a report are:
- Connect to the Graph with the Directory.Read.All scope.
- Find all administrative units (regular, dynamic, and restricted) with the Get-MgBetaDirectoryAdministrativeUnit cmdlet.
- Retrieve the role assignments for administrative units using the Get-MgBetaRoleManagementDirectoryRoleAssignment cmdlet. Role assignments allow specific user accounts to perform management tasks for the user accounts, groups, and devices in an administrative unit. Holders of regular administrative roles like Global administrator and User administrator can manage objects in regular administrative units but are blocked from restricted administrative units. Only users specifically assigned roles scoped to restricted administrative units can manage objects in these units.
- Loop through each administrative unit to record details of its settings.
- Find the role assignments specific to the administrative unit and extract details of the user accounts, groups, or service principals holding roles.
- Fetch details of the members of the administrative unit with the Get-MgBetaAdministrativeUnitMember cmdlet. For dynamic administrative units, the cmdlet returns the set of objects based on the membership rule defined in the administrative unit (like the way dynamic groups or even dynamic distribution lists work).
- Update a PowerShell list with details of the administrative unit, the assignments, and its membership.
- Output results in a CSV file and an HTML page.
As you can see from the list of processing steps, the cmdlets used to process administrative units use the beta endpoint. Other cmdlets in the script, like Get-MgUser and Get-MgGroup, use the V1.0 endpoint. This is a good example of how scripts can mix and match beta and V1.0 cmdlets to do a job.
Analyzing Results
Figure 1 shows the HTML page generated for my tenant. The first thing to note is that there are two administrative units without members, which means that the objects are essentially useless. Such a condition can evolve over time if all the user accounts, groups, and devices that were members of an administrative unit depart for one reason or another. This might be deletions of individual accounts or the wholesale movement of objects from one tenant to another. For dynamic administrative units, it might be that the membership rules to calculate the membership return nothing because of problems in user account properties. Or just that an administrator created an administrative unit with some purpose in mind that never happened.
You can see the membership rules for dynamic administrative units listed in a column. Where specific role assignments are present, they’re listed with the display name of the assignee and their type (user, group, or service principal). I assign roles to service principals for Azure Automation accounts to allow their runbooks to process subsets of user accounts.
If no specific role assignments exist for an administrative unit, the report lists “Administrator Roles” to indicate that normal administrator role assignments apply. The scope of each administrative unit is listed with “Directory,” meaning that it is unrestricted, and “Restricted” meaning that only those with specific role assignments for the administrative unit can manage its membership.
There’s no magic in the script, and the PowerShell is quite straightforward. The hardest part of writing scripts like this is to find the correct SDK cmdlet to use and understand the output returned by the cmdlet. You can download the complete script from GitHub. All suggestions are welcome and you can propose changes to the script through GitHub.
Finding Accounts Covered by Restricted Administrative Units
Finally, a note about how to discover the set of user accounts covered by restricted administrative units. When a user account comes within the scope of a restricted administrative unit, Entra ID sets its IsManagementRestricted property to True. Finding the set of accounts is therefore a matter of checking this property. Regretfully, server-side filtering is currently unsupported, so a command like this must be run:
Get-MgBetaUser -Filter "usertype eq 'Member'" -All | where-Object {$_.IsManagementRestricted -eq $True}
DIY Reporting
I’ve never understood why Microsoft pays relatively little attention to reporting different aspects of Microsoft 365/Entra ID. Reports that help Microsoft sell more licenses (like usage reports) are available in the Microsoft 365 admin center and other portals, but not much else. On the upside, you get a chance to write your own reports. The downside of that is the work that’s required, even if it does fill a couple of hours on a wet Saturday afternoon.
Hi Tony, Connect-MgGraph supporting Managed Identities is great and I know the Exchange Powershell has it as well, but do you know if/when support for Compliance PowerShell will come?
I’m trying to grab eDisocvery Premium case names in my script since the audit log only contains the case ID (while eDiscovery Standard log entries have the case name in them). I can query the audit log with Exchange Online PS with Managed Identity, but getting case metadata through Compliance PS won’t work with Managed Identity.
I also tried Graph API but it seems like Get-MgSecurityCaseEdiscoveryCase is only supported from user context as described in https://learn.microsoft.com/en-us/graph/api/ediscovery-case-get?view=graph-rest-beta&tabs=http#permissions
Given the normal pace, I’d imagine that managed identity support for the compliance endpoint should come within the next three months, but that’s only an educated (or silly) guess on my part.
Maybe you could write a script to get all the eDiscovery metadata and export it as a CSV file that could be downloaded and used by a runbook? The data shouldn’t change all that much unless you have a lot of eDiscovery cases going on.