# Export-PermissionAnalysisReport
SYNOPSIS
Generates an interactive HTML report for Microsoft Graph permission analysis results.
SYNTAX
Export-PermissionAnalysisReport [-AppData] [[-OutputPath] ] [[-ReportTitle] ]
[-ProgressAction ] []
DESCRIPTION
This function creates a comprehensive, interactive HTML report that visualizes permission analysis
results for Microsoft Graph applications.
The report provides a user-friendly interface for reviewing
permission optimization opportunities, API activity patterns, and throttling statistics.
The generated report features:
- Dark/Light Mode Toggle: User preference for viewing comfort
- Interactive Data Tables: Sortable and filterable tables for all data views
- Permission Status Indicators: Color-coded badges showing optimal, excess, and missing permissions
- Throttling Statistics: Visual severity indicators and detailed metrics
- Detailed Modal Views: Click any application for comprehensive details
- CSV Export: Export filtered data for further analysis
- Search and Filter: Real-time filtering across all applications
- Responsive Design: Works seamlessly on desktop and mobile devices
- Offline Capable: Once generated, works without internet connection
Report Sections:
1.
Summary Statistics: Overview of total apps, permissions, and coverage
2.
Applications Table: Sortable list with key metrics per application
3.
Application Details: Click any row to see:
- Current vs.
optimal permission comparison
- API activity breakdown with method and endpoint details
- Throttling statistics and health indicators
- Permission recommendations
The function processes application analysis data (typically from Get-PermissionAnalysis),
embeds it as JSON into an HTML template with Tailwind CSS styling, and generates a
standalone HTML file that can be shared, archived, or viewed in any modern browser.
Use Cases:
- Security Audits: Document permission analysis for compliance requirements
- Permission Right-Sizing: Identify and communicate permission optimization opportunities
- Change Management: Create before/after reports for permission changes
- Executive Reporting: Visual, easy-to-understand permission health dashboard
- Historical Tracking: Archive reports over time to track permission hygiene trends
EXAMPLES
EXAMPLE 1
$results = Get-PermissionAnalysis -WorkspaceId $wsId -Days 30
$reportPath = Export-PermissionAnalysisReport -AppData $results -OutputPath ".\reports\monthly-analysis.html"
Start-Process $reportPath
Description:
Analyzes 30 days of activity, generates a report, and immediately opens it in the default browser.
EXAMPLE 2
Get-PermissionAnalysis -WorkspaceId $wsId -Days 90 -ApplicationId $criticalApps |
Export-PermissionAnalysisReport -OutputPath "C:\Reports\Critical_Apps_$(Get-Date -Format 'yyyyMMdd').html" -ReportTitle "Critical Applications - Q4 Analysis"
Description:
Analyzes specific critical applications over 90 days, generates a timestamped report
with a custom title, saved to a dedicated reports folder.
EXAMPLE 3
# Compare current vs. previous month
$thisMonth = Get-PermissionAnalysis -WorkspaceId $wsId -Days 30
$lastMonth = Get-PermissionAnalysis -WorkspaceId $wsId -Days 60 | Where-Object {
$_.LastActivityDate -lt (Get-Date).AddDays(-30)
}
Export-PermissionAnalysisReport -AppData $thisMonth -OutputPath ".\reports\current-month.html" -ReportTitle "Current Month"
Export-PermissionAnalysisReport -AppData $lastMonth -OutputPath ".\reports\last-month.html" -ReportTitle "Previous Month"
Description:
Generates two separate reports for comparison between time periods to identify
permission drift or changes in application behavior.
EXAMPLE 4
# Filter and report on problematic applications only
$allResults = Get-PermissionAnalysis -WorkspaceId $wsId -Days 30
$problematic = $allResults | Where-Object {
$_.ExcessPermissions.Count -gt 5 -or
$_.RequiredPermissions.Count -gt 0 -or
$_.ThrottlingStats.ThrottlingSeverity -ge 3
}
if ($problematic.Count -gt 0) {
$report = Export-PermissionAnalysisReport -AppData $problematic -OutputPath ".\ActionRequired.html" -ReportTitle "Applications Requiring Attention"
"Found $($problematic.Count) applications requiring attention.
Report: $report"
} else {
"All applications are optimally configured!"
}
Description:
Filters analysis results to only applications with significant issues (excess permissions,
missing permissions, or throttling), generating a focused action-required report.
PARAMETERS
-AppData
An array of application permission analysis objects, typically from Get-PermissionAnalysis.
This parameter accepts pipeline input, allowing multiple applications to be processed efficiently.
Each object should contain the following properties:
Required Properties:
- PrincipalName (String): The display name of the application or service principal
- PrincipalId (String): The Azure AD object ID of the service principal
- CurrentPermissions (Array): Currently assigned Microsoft Graph permissions (strings)
- OptimalPermissions (Array): Optimal permission objects with:
* Permission (String): The permission name
* ActivitiesCovered (Int): Number of activities this permission covers
- ExcessPermissions (Array): Permissions assigned but not needed based on activity
- RequiredPermissions (Array): Permissions needed but not currently assigned
- Activity (Array): API activity objects with:
* Method (String): HTTP method (GET, POST, etc.)
* Uri (String): API endpoint called
- UnmatchedActivities (Array): Activities that couldn't be matched to permission maps
- MatchedAllActivity (Boolean): True if all activities were successfully matched
- AppRoleCount (Int): Total number of Microsoft Graph app roles assigned
Optional Properties:
- ThrottlingStats (PSCustomObject): Throttling statistics with:
* TotalRequests (Int): Total API requests
* Total429Errors (Int): Throttling error count
* ThrottleRate (Double): Percentage of throttled requests
* ThrottlingStatus (String): Severity classification (Normal, Warning, Critical, etc.)
Type: Array
Parameter Sets: (All)
Aliases:
Required: True
Position: 1
Default value: None
Accept pipeline input: True (ByValue)
Accept wildcard characters: False
-OutputPath
The file path where the HTML report will be saved.
Can be absolute or relative path.
Default: ".\PermissionAnalysisReport.html" (current directory)
Tips:
- Use timestamped filenames for historical tracking
- Ensure the directory exists or the function will fail
- .html extension is recommended for browser association
Type: String
Parameter Sets: (All)
Aliases:
Required: False
Position: 2
Default value: .\PermissionAnalysisReport.html
Accept pipeline input: False
Accept wildcard characters: False
-ReportTitle
The title displayed in the report header and browser tab.
This appears at the top of
the report and in the browser's title bar/tab.
Default: "Microsoft Graph Permission Analysis Report"
Use Cases:
- Include environment: "Production Apps - Graph Permissions"
- Add time period: "Q4 2024 Permission Analysis"
- Specify department: "HR Department - Graph API Audit"
Type: String
Parameter Sets: (All)
Aliases:
Required: False
Position: 3
Default value: Microsoft Graph Permission Analysis Report
Accept pipeline input: False
Accept wildcard characters: False
-ProgressAction
{{ Fill ProgressAction Description }}
Type: ActionPreference
Parameter Sets: (All)
Aliases: proga
Required: False
Position: Named
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
CommonParameters
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see
about_CommonParameters.
OUTPUTS
System.String
Returns the full absolute path to the generated HTML report file.
This allows for easy chaining with other commands like Start-Process to open the report,
or copy operations to move it to a shared location.
NOTES
Prerequisites:
- PowerShell 5.1 or later
- Module must be properly installed with data\base.html template file
- Write permissions to the output directory
Template Architecture:
- The function uses a Jinja2-style template with placeholder blocks
- Template location: \\data\base.html
- Placeholders replaced:
* {% block app_data %}{% endblock %} -\> JSON data
* {% block title %}{% endblock %} -\> Report title
* {% block generated_on %}{% endblock %} -\> Generation timestamp
JSON Processing:
- Application data converted to JSON with depth 10 (preserves nested structures)
- Special characters properly escaped for JavaScript embedding:
* Backslashes: \ -\> \\\\
* Quotes: " -\> \"
* Newlines: \n -\> \\\\n
- Data is compressed (no indentation) to reduce file size
Report Size Considerations:
- Typical report: 500KB - 2MB depending on number of applications
- Large deployments (100+ apps): May reach 5-10MB
- Consider splitting very large tenants into multiple reports
- All data embedded in single HTML file (no external dependencies)
Browser Compatibility:
- Requires modern browser (released within last 2 years):
* Chrome/Edge: Version 90+
* Firefox: Version 88+
* Safari: Version 14+
- JavaScript must be enabled
- Works fully offline once generated
- No server-side processing required
Security Considerations:
- Reports may contain sensitive information (app names, permission details)
- Store reports securely with appropriate access controls
- Consider encrypting archived reports
- Sanitize application names if sharing externally
- No credentials or secrets are included in reports
Performance:
- Report generation: ~1-2 seconds for 50 applications
- Browser rendering: ~2-5 seconds for 100 applications
- Search/filter: Real-time (\< 100ms for typical datasets)
- Large datasets (500+ apps) may cause slower browser performance
Troubleshooting:
If "Template file not found" error:
- Verify module is properly installed: Get-Module LeastPrivilegedMSGraph -ListAvailable
- Check module path: (Get-Module LeastPrivilegedMSGraph).ModuleBase
- Ensure data\base.html exists in module directory
- Reinstall module if template is missing
If report displays incorrectly:
- Clear browser cache and reload
- Try a different browser
- Check browser console for JavaScript errors (F12)
- Verify the HTML file isn't corrupted (should be valid UTF-8)
If data appears truncated:
- Check that ConvertTo-Json depth (10) is sufficient for nested data
- Review input data structure for unexpected nesting
- Consider simplifying input data if depth exceeds 10 levels
Common Use Cases:
1.
Monthly Security Reviews: Generate reports for security team review
2.
Audit Documentation: Create compliance documentation for auditors
3.
Change Requests: Attach reports to permission change requests
4.
Trend Analysis: Archive monthly reports to track improvements
5.
Stakeholder Communication: Share visual reports with management
6.
Incident Response: Document permission state during investigations
Best Practices:
- Use consistent naming conventions for output files
- Include timestamps for historical tracking
- Store reports in version-controlled or backed-up locations
- Review reports regularly (weekly/monthly depending on environment)
- Act on recommendations within 30 days
- Archive reports for compliance (typically 1-7 years retention)