Reporting User and Group Assignments for Enterprise Applications

How to Find and Document Assignments for Entra ID Enterprise Applications

A reader asked:

I am trying to execute Microsoft Graph that it can grab all my Enterprise Applications in my tenancy and export to CSV the application name and user and groups assigned to the groups.”

There’s a couple of things to unpack here before discussing potential answers. First, enterprise applications are Entra ID registered applications. Companies like Microsoft or Apple create enterprise applications for use in multiple tenants. For example, if you signed up to attend a Microsoft conference using your Entra ID credentials, the process is handled by an enterprise app called Microsoft Events. The home tenant identifier registered for the app is 72f988bf-86f1-41af-91ab-2d7cd011db47, which this site tells us is the identifier for Microsoft’s tenant.

Often enterprise applications act as an entry point to a service. For example, the properties of the IdPowerToys app (Figure 1) contain a link to the site where the service runs to document conditional access policies in PowerPoint.

Enterprise app registration for the idPowerToys app
Figure 1: Enterprise app registration for the idPowerToys app

Service Principals

When an enterprise application is used within a tenant, Entra ID creates a service principal to hold the permissions and assignments for the application within that tenant. If you want, the service principal is the instantiation of the application within the tenant that holds permissions and other information for the application. Other objects, like Azure Automation accounts also have service principals used to hold permissions and roles, such as those needed to access user data via Graph APIs.

By default, enterprise applications are accessible by all users. To control access, administrators can update application properties to require assignment. This means that Entra ID will only issue an access token for the application to users and groups granted access through assignment. It is the way to lock down access to enterprise applications.

Finding Enterprise Applications

To answer the question, we must find the set of enterprise applications in the tenant that are homed in other tenants. The way to do this is to run the Get-MgServicePrincipal cmdlet from the Microsoft Graph PowerShell SDK. Two steps are necessary. First, find the service principals known in the tenant. Second, filter the set to extract those with a tenant identifier that is not the same as your tenant:

[array]$ServicePrincipals = Get-MgServicePrincipal -All
[array]$EnterpriseApps = $ServicePrincipals | Where-Object {$_.AppOwnerOrganizationId -ne $TenantId} | Sort-Object DisplayName

The filter shown above creates a set of enterprise apps. If you want to further refine the filter to only find apps where role assignment is required, change it to:

 [array]$EnterpriseApps = $ServicePrincipals | Where-Object {$_.AppOwnerOrganizationId -ne $TenantId -and $_.AppRoleAssignmentRequired -eq $True} | `
        Sort-Object DisplayName

The next step is to loop through the set of apps and run the Get-MgServicePrincipalAppRoleAssignedTo cmdlet to check if any assignments exist. If any do, it’s easy to grab the details for a report.

ForEach ($App in $EnterpriseApps) {
    [array]$Assignments = Get-MgServicePrincipalAppRoleAssignedTo -ServicePrincipalId $App.Id | Where-Object {$_.PrincipalType -ne 'ServicePrincipal'}
    If ($Assignments) {
        $i++
        Write-Host ("Found assignments for {0}" -f $App.DisplayName)
        ForEach ($Assignment in $Assignments) {
            $ReportLine = [PSCustomObject]@{
                TimeStamp   = $Assignment.CreatedDateTime  
                Id          = $Assignment.Id
                DisplayName = $Assignment.PrincipalDisplayName 
                UserId      = $Assignment.PrincipalId
                Type        = $Assignment.PrincipalType
                Resource    = $Assignment.ResourceDisplayName
                ResourceId  = $Assignment.ResourceId
            }
            $Report.Add($ReportLine)
        }
    }

Note the filter used with the Get-MgServicePrincipalAppRoleAssignedTo cmdlet. This removes assignments to service principals such as those used to hold permissions for Azure Automation accounts. Here’s an example of an assignment to an Azure Automation account to allow it to act like an account holding the Exchange Administrator role.

TimeStamp   : 28/01/2022 15:47:35
Id          : ag5Go0LJzUWdGNo2BTCsaYJIbAAI79JLkTVN2fzhjh0
DisplayName : ExoAutomationAccount_Y6LgjDYIfPnxmFzrqdbaClsnTD/gN4BNnVMywiju5hk=
UserId      : a3460e6a-c942-45cd-9d18-da360530ac69
Type        : ServicePrincipal
Resource    : Office 365 Exchange Online
ResourceId  : dacf6086-a190-467a-aadd-d519472b8d1d

You can download the script I used from GitHub.

The Output

After filtering, what remains are the app assignments to users and groups, the details of which the script captures and reports. Figure 2 shows an example of the output.

Enterprise apps and user/group assignments
Figure 1: Enterprise apps and user/group assignments

My name features heavily in the list because I installed many of the apps in my tenant. Some of the apps and associated assignments are quite old, a fact that underlines the need to review and remove unused or obsolete apps periodically. The duplicate entries for the Graph Explorer is due to an assignment captured when the app was first installed followed by an explicit assignment to prevent access to the app to anyone but my account.

None of this is particularly difficult to do. The trick, as is often the case with Microsoft 365, is to know where to start looking. And perhaps some luck when navigating through the documentation!


Insight like this doesn’t come easily. You’ve got to know the technology and understand how to look behind the scenes. Benefit from the knowledge and experience of the Office 365 for IT Pros team by subscribing to the best eBook covering Office 365 and the wider Microsoft 365 ecosystem.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.