List Custom Entra Apps With High-Risk Permissions Using PowerShell

In Microsoft Entra ID, custom applications often interact with Microsoft Graph and other services using API permissions. While these permissions enable powerful integrations, some of them are considered high-risk because they grant extensive access to directory data, users, groups, and files.

Examples of such permissions include: i) Directory.ReadWrite.All, ii) User.ReadWrite.All, iii) Group.ReadWrite.All. Identifying custom (non-template) Entra apps with high-risk permissions is critical for: i) Security audits, ii) Compliance enforcement, iii) Least privilege validation and iv)Threat detection.

Using Microsoft Graph PowerShell, administrators can scan all applications, detect high-risk permissions, and export a detailed report for analysis.

Download this script from our M365Corner GitHub Repo: https://github.com/m365corner/M365Corner-Scripts/tree/main/Entra-Apps-Related-Scripts/List-Custom-Entra-Apps-With-High-Risk-Permissions

🚀 Community Edition Released!

Try the M365Corner Microsoft 365 Reporting Tool — your DIY pack with 20+ out-of-the-box M365 reports for Users, Groups, and Teams.

The Script

                            
# Connect to Microsoft Graph
Connect-MgGraph -Scopes Application.Read.All

Write-Host "Scanning custom applications with high-risk permissions..." -ForegroundColor Cyan

# Define high-risk permissions
$HighRiskPermissions = @(
"Directory.ReadWrite.All",
"User.ReadWrite.All",
"Application.ReadWrite.All",
"RoleManagement.ReadWrite.Directory",
"Group.ReadWrite.All",
"Mail.ReadWrite",
"Files.ReadWrite.All"
)

# Get applications
$Applications = Get-MgApplication -All -Property Id,DisplayName,AppId,CreatedDateTime,Description,ApplicationTemplateId,RequiredResourceAccess

$Results = @()

foreach ($App in $Applications) {

    # Only process custom (non-template) apps
    if ($App.ApplicationTemplateId) {
        continue
    }

    $MatchedPermissions = @()

    foreach ($Resource in $App.RequiredResourceAccess) {

        foreach ($Access in $Resource.ResourceAccess) {

            $PermissionId = $Access.Id

            # Resolve permission name
            $ServicePrincipal = Get-MgServicePrincipal -Filter "appId eq '$($Resource.ResourceAppId)'" -Property AppRoles,Oauth2PermissionScopes

            $PermissionName = ($ServicePrincipal.AppRoles + $ServicePrincipal.Oauth2PermissionScopes | Where-Object {$_.Id -eq $PermissionId}).Value

            if ($HighRiskPermissions -contains $PermissionName) {
                $MatchedPermissions += $PermissionName
            }
        }
    }

    if ($MatchedPermissions.Count -gt 0) {

        # Console output (minimal)
        Write-Host "$($App.DisplayName) | $($App.AppId)" -ForegroundColor Red

        # Export object (detailed)
        $Results += [PSCustomObject]@{
            ApplicationName     = $App.DisplayName
            ApplicationId       = $App.Id
            ClientId            = $App.AppId
            CreatedDate         = $App.CreatedDateTime
            Description         = $App.Description
            AppType             = "Custom (Non-Template)"
            HighRiskPermissions = ($MatchedPermissions -join ", ")
            RiskLevel           = "High"
        }
    }
}

# Export results
$ExportPath = "D:\CustomApps_HighRiskPermissions_Report.csv"

$Results | Export-Csv $ExportPath -NoTypeInformation

Write-Host "Report exported to $ExportPath" -ForegroundColor Cyan
                            


How the Script Works

Step Description
Connect to Graph Authenticates using Application.Read.All permission
Define High-Risk Permissions Creates a predefined list of sensitive Graph permissions
Retrieve Applications Uses Get-MgApplication -All to fetch all applications with required properties
Filter Custom Apps Skips template-based apps that contain ApplicationTemplateId value
Extract Permissions Iterates through RequiredResourceAccess to identify assigned permissions
Resolve Permission Names Maps permission IDs to readable names using Get-MgServicePrincipal
Match High-Risk Permissions Compares permissions against predefined high-risk list
Build Report Stores apps with matched permissions in a structured object
Export Results Outputs data to a CSV report

Further Enhancements

Enhancement Description
Include Owner Details Add Get-MgApplicationOwner to identify responsible users
Add Permission Type Differentiate between delegated and application permissions
Risk Categorization Categorize permissions into Medium / High / Critical
Include Last Sign-In Combine with sign-in logs to detect inactive risky apps
Alerting Mechanism Send alerts when new high-risk apps are detected

Frequently Asked Questions

Question Answer
What are high-risk entra app permissions? Permissions that grant extensive access to directory, users, or data
Why focus on custom entra apps? Custom entra apps often bypass standard governance controls
How are permissions identified? By mapping permission IDs to permission names via service principals
Can template based entra apps also have high-risk permissions? Yes, but this script intentionally excludes them
Is this script suitable for large tenants? Yes, but performance can be improved with filtering

Admin Usecases

Use Case Description
Security Audit Identify apps with excessive permissions
Compliance Checks Ensure apps follow least privilege principles
Threat Detection Detect potentially malicious or over-permissioned apps
Governance Reporting Maintain visibility over sensitive application access
App Review Process Validate permissions before approving applications

Possible Errors & Solutions

Error Cause Solution
Insufficient privileges Missing Graph permissions Use Application.Read.All with admin consent
Slow execution Large number of apps Optimize by filtering or batching requests
Cmdlet not recognized Graph module not installed Install using Install-Module Microsoft.Graph
Access token expired Session timeout Reconnect using Connect-MgGraph
Empty results No high-risk apps found Validate permission list and tenant data

Conclusion

Custom Entra applications with high-risk permissions can pose significant security risks if not properly monitored. These permissions often grant deep access to sensitive data and directory operations, making them a critical focus area for administrators

This Microsoft Graph PowerShell script provides a powerful way to identify, analyze, and report custom applications with high-risk permissions, enabling better governance and proactive security management.

By incorporating this script into regular audits and automation workflows, organizations can strengthen their security posture, enforce least privilege principles, and reduce potential attack surfaces in their Entra ID environment.

Graph PowerShell Explorer Widget

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


Permission Required

Example:


                            


                            


                            

© Created and Maintained by LEARNIT WELL SOLUTIONS. All Rights Reserved.