Exporting All Access Packages\Settings and Roles Assigned

H Raja 221 Reputation points

Hi, I'm trying to find out a way to export all Access Packages with settings in my Tenant with Roles assigned. You can't seem seem to export this information via the portal, does any of the nice folks here have a Powershell Script that can achieve this please. I don't really want to be going to each Access Packages and checking each setting. I hope that makes sense. Thanks

Microsoft Entra ID
Microsoft Entra ID
A Microsoft Entra identity service that provides identity management and access control capabilities. Replaces Azure Active Directory.
20,193 questions
{count} votes

Accepted answer
  1. JamesTran-MSFT 36,511 Reputation points Microsoft Employee

    @H Raja
    Thank you for your post!

    Adding onto what @Vasil Michev mentioned, you can try a 3rd party PowerShell script that I found from a customer question on our Azure Governance and Management Tech Community. For more info - Access Package Export

    Generating report of all Access Package assignments in Azure AD Entitlement Management:

       Get graph explorer access token by sending the user to sign in and asking to copy url  
    function Get-GraphExplorerAccessToken  
            [String[]] $Scopes = "User.Read.All"  
        $url = "https://login.microsoftonline.com/common/oauth2/v2.0/authorize?nonce=graph_explorer&prompt=select_account&client_id=de8bc8b5-d9f9-48b1-a8ad-b748da725064&response_type=token&redirect_uri=https%3A%2F%2Fdeveloper.microsoft.com%2Fen-us%2Fgraph%2Fgraph-explorer&scope={0}" -f ($Scopes -join "+")  
        $url | Set-Clipboard  
        Write-Verbose "Please do the following:"  
        Write-Verbose ""  
        Write-Verbose "1. Go to the url on the clipboard"  
        Write-Verbose "2. Sign in with an account that has the required access"  
        Write-Verbose "3. Accept any consent (remember, this is the Microsoft Graph Explorer app, not a funky one)"  
        Write-Verbose "4. When back at the Graph Explorer, copy the url in the address bar (should now contain #access_token=...)"  
        # Loop and wait to find access token on the clipboard  
        $accessToken = $null  
        do {  
            $clipboardContent = Get-Clipboard  
            if($clipboardContent -like "*#access_token=*") {  
                $accessToken = ($clipboardContent -split "[#&]" | Where{$_ -like "access_token=*"}) -replace "access_token="  
                # Create base64 value of correct length (multiple of 4)  
                $base64 = $accessToken.Split(".")[1]  
                while(($base64.Length % 4) -ne 0) {  
                    $base64 += "="  
                $accessTokenDecoded = [System.Text.Encoding]::UTF8.GetString(([System.Convert]::FromBase64String($base64))) | ConvertFrom-Json  
                $scopesInToken = $accessTokenDecoded.scp -split " "  
                $Scopes |   
                    Where{$_ -notin $scopesInToken} |  
                        Write-Warning "Token does not contain scope $($_)"  
            } else {  
                sleep -Milliseconds 100  
        } while(!$accessToken)  
        Write-Verbose "Access token found!"  
        return $accessToken  
    # Get access token and build rest param (parameters for Invoke-RestMethod)  
    $token = Get-GraphExplorerAccessToken -Verbose -Scopes "User.Read.All","EntitlementManagement.ReadWrite.All"  
    $restParams = @{Headers = @{Authorization = "Bearer $token"}}  
    # Endpoints  
    $graphBase = "https://graph.microsoft.com/beta"  
    $endpoints = @{  
        accessPackageCatalogs = "{0}/identityGovernance/entitlementManagement/accessPackageCatalogs" -f $graphBase  
        accessPackages = "{0}/identityGovernance/entitlementManagement/accessPackages?`$top=999" -f $graphBase  
        accessPackageAssignments = "{0}/identityGovernance/entitlementManagement/accessPackageAssignments?`$top=999" -f $graphBase  
        users = "{0}/users" -f $graphBase  
        groups = "{0}/groups" -f $graphBase  
        accessPackageAssignmentPolicies = "{0}/identityGovernance/entitlementManagement/accessPackageAssignmentPolicies?`$top" -f $graphBase  
        me = "{0}/me" -f $graphBase  
        directoryObjects = "{0}/directoryObjects" -f $graphBase  
    # Get all access packages (TODO: Add paging support ot support more than 999 access packages)  
    Write-Verbose "Getting all access packages..." -Verbose   
    $AccessPackages = Invoke-RestMethod $endpoints.accessPackages @restParams  
    if(($AccessPackages.value|measure).Count -gt 0) {  
        $AccessPackagesMap = $AccessPackages.value | Group-Object -AsHashTable -Property id -AsString  
        Write-Verbose "Found $($AccessPackagesMap.Count) access packages" -Verbose  
    } else {  
        Write-Error "No access packages found!" -ErrorAction Stop  
    # Get all access package assignment policies  
    Write-Verbose "Getting all access package assignment policies..." -Verbose   
    $AccessPackageAssignmentPolicies = Invoke-RestMethod $endpoints.accessPackageAssignmentPolicies @restParams  
    if(($AccessPackageAssignmentPolicies.value|measure).Count -gt 0) {  
        $AccessPackageAssignmentPoliciesMap = $AccessPackageAssignmentPolicies.value | Group-Object -AsHashTable -Property id -AsString  
        Write-Verbose "Found $($AccessPackageAssignmentPoliciesMap.Count) access package assignment policies" -Verbose  
    } else {  
        Write-Error "No access package assignment policies found!" -ErrorAction Stop  
    # Get all access package assignments  
    Write-Verbose "Getting all access package assignments..." -Verbose   
    $url = "https://graph.microsoft.com/beta/identityGovernance/entitlementManagement/accessPackageAssignments?`$expand=target"  
    $AccessPackageAssignments = New-Object System.Collections.ArrayList  
    while($url) {  
        $_Result = Invoke-RestMethod $url @restParams  
        $url = $_Result.'@odata.nextLink'  
        if($_Result.value) {  
            $AccessPackageAssignments.AddRange($_Result.value) | Out-Null  
    Write-Verbose "Found $($AccessPackageAssignments.Count) access package assignments" -Verbose  
    # Process into objects  
    Write-Verbose "Processing access package assignments" -Verbose  
    $Report = $AccessPackageAssignments | ForEach-Object {  
        [PSCustomObject] @{  
            AccessPackageId = $_.AccessPackageId  
            AccessPackageName = $AccessPackagesMap[$_.AccessPackageId].DisplayName  
            AssignmentPolicyId = $_.AssignmentPolicyId  
            AssignmentPolicy = $AccessPackageAssignmentPoliciesMap[$_.AssignmentPolicyId].DisplayName  
            AssignmentStatus = $_.AssignmentStatus  
            AssignmentState = $_.AssignmentState  
            IsExtended = $_.IsExtended  
            ExpiredDateTime = $_.ExpiredDateTime  
            Target = $_.Target.ObjectId  
            TargetDisplayName = $_.Target.DisplayName  
            TargetUPN = $_.Target.PrincipalName  
    $Report | Out-GridView  
    Install-Module ExportExcel -Scope CurrentUser  
    $Report | Export-Excel -Path ~\Desktop\report.xlsx -AutoSize -AutoFilter  

    Additional Links:
    MS Graph REST API - accessPackage resource type
    MS Graph REST API - accessPackageCatalog resource type

    If you have any other questions, please let me know.
    Thank you for your time and patience throughout this issue.


    Please remember to "Accept Answer" if any answer/reply helped, so that others in the community facing similar issues can easily find the solution.

    0 comments No comments

1 additional answer

Sort by: Most helpful
  1. Vasil Michev 98,681 Reputation points MVP

    Try this Graph API query:

    GET https://graph.microsoft.com/beta/identityGovernance/entitlementManagement/accessPackages?$expand=accessPackageResourceRoleScopes($expand=accessPackageResourceRole,accessPackageResourceScope)

    It will output all access packages and roles/scopes.