Get direct and transitive Entra role assignments with PowerShell
- romanvitsinskyi
- Jun 15
- 1 min read
Updated: 6 days ago

Default Entra report available for download in admin portal has some limitation as it will not provide transitive assignments (if user gets Entra role via group membership). You can use code below based on Graph API to list all assignments, direct and transitive, for all users.
Note: this report will only provide list of roles assigned to users. If you need to report all assignments, you'll also need to include Service Principals.
Connect-AzureAD
Connect-MgGraph -Scopes "User.Read.All","AuditLog.Read.All"
$All_Roles = Get-AzureADMSRoleDefinition
$All_Users = Get-MgUser -Property SignInActivity -All
$i = 0
$Roles_report = @()
foreach ($user in $All_Users)
{
$i++
Write-Progress -Activity "Gathering info..." -CurrentOperation "$i out of $($All_Users.count)" -PercentComplete ($i/$($All_Users.count)*100)
$response = $user_roles = $null
$uri = "https://graph.microsoft.com/beta/roleManagement/directory/transitiveRoleAssignments?`$count=true&`$filter=principalId eq '$($user.Id)'"
$method = 'GET'
$headers = @{'ConsistencyLevel' = 'eventual'}
$response = (Invoke-MgGraphRequest -Uri $uri -Headers $headers -Method $method -Body $null).value
if ($response)
{
$user_roles = ($response.roleDefinitionId | %{$roleId = $_; $All_Roles | ? {$_.Id -eq $roleId}}).DisplayName
$principalIds = try {$response.principalId | % {Get-AzureADObjectByObjectId -ObjectIds $_}} catch {}
$Roles_report +=$user | Select DisplayName, UserPrincipalName, AccountEnabled, UserType, @{N="Roles"; E={$user_roles | out-string}}, @{N="Assigned via"; E={$principalIds.DisplayName | out-string}}, CompanyName,Department,JobTitle,CreatedDateTime, @{N="LastSignIn"; E={$user.SignInActivity.LastSignInDateTime}}
}
}
Write-Progress -Activity "Gathering info..." -Completed