Open-source Microsoft 365 license analysis and optimization tool for Tabletop Exercises and strategic planning
M365 License Analyzer is a comprehensive toolkit designed to help organizations conduct license optimization tabletop exercises. It collects Microsoft 365 license assignment data, imports it into a PostgreSQL database, and provides visualization through Grafana dashboardsβenabling data-driven decisions about license allocation, cost optimization, and compliance.
- β Automated License Inventory - PowerShell scripts to collect M365 license data via Microsoft Graph API
- β Flexible Deployment - Run standalone scripts or deploy full PostgreSQL + Grafana stack
- β Docker Support - One-command deployment with docker-compose
- β Sample Data Included - Test with anonymized data before connecting to your tenant
- β Grafana Dashboards - Pre-built visualizations for license utilization and optimization
- β Group-Based Licensing Analysis - Understand how licenses are assigned through groups
- β Inactive User Detection - Identify unused licenses for cost savings
- β Export Options - CSV and HTML reports for executive briefings
Perfect for quick assessments without database infrastructure.
# 1. Clone the repository
git clone https://github.com/MSSecCSA/M365LicenseAnalyzer-Public.git
cd M365LicenseAnalyzer-Public
# 2. Configure settings (interactive)
.\Setup-Configuration.ps1 -Interactive
# 3. Connect to Microsoft 365 and generate inventory
.\scripts\Generate-LicenseInventory.ps1
# Output: data/exports/LicenseInventory_YYYYMMDD.csvBest for ongoing monitoring and visual dashboards.
# 1. Clone and configure
git clone https://github.com/MSSecCSA/M365LicenseAnalyzer-Public.git
cd M365LicenseAnalyzer-Public
.\Setup-Configuration.ps1 -Interactive
# 2. Start Docker stack (PostgreSQL + Grafana)
.\docker\start-stack.ps1
# 3. Collect license data
.\scripts\Generate-LicenseInventory.ps1
# 4. Import to database
.\scripts\Import-ToPostgreSQL.ps1 -UseDocker
# 5. Open Grafana
Start-Process "http://localhost:3000"
# Login: admin / (password from .env file)- PowerShell 5.1+ (Windows) or PowerShell 7+ (Cross-platform)
- Microsoft Graph PowerShell SDK
Install-Module Microsoft.Graph -Scope CurrentUser
- Docker Desktop (for containerized PostgreSQL + Grafana)
Your account needs these Microsoft Graph API permissions:
User.Read.AllOrganization.Read.AllDirectory.Read.All
Note: Global Reader or License Administrator roles typically have these permissions.
- Installation Guide - Detailed setup for all deployment scenarios
- Configuration Guide - Understanding config.json and environment variables
- Usage Guide - Running scripts and interpreting results
- Docker Guide - Container deployment and troubleshooting
- Grafana Setup - Dashboard configuration and customization
- Tabletop Exercise Guide - How to run a license optimization workshop
- Data Schema - Database structure and relationships
- Troubleshooting - Common issues and solutions
- Contributing - How to contribute to this project
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Microsoft 365 Tenant β
β (Users, Licenses, Groups, Activity Data via Graph API) β
βββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββββ
β
β Microsoft Graph API
β (PowerShell SDK)
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β M365 License Analyzer (This Tool) β
β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β PowerShell Scripts β β
β β β’ Generate-LicenseInventory.ps1 β β
β β β’ Import-ToPostgreSQL.ps1 β β
β ββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββββ β
β β β
β βΌ β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β CSV Exports (data/exports/) β β
β β β’ License inventory β β
β β β’ User activity β β
β β β’ Group assignments β β
β ββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββββ β
β β β
β βΌ β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β PostgreSQL Database (Docker/Standalone) β β
β β β’ sku_inventory β β
β β β’ user_licenses β β
β β β’ user_activity β β
β β β’ licensing_groups β β
β ββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββββ β
β β β
β βΌ β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Grafana Dashboards (Docker/Standalone) β β
β β β’ License utilization β β
β β β’ Cost analysis β β
β β β’ Inactive users β β
β β β’ Group-based licensing β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Facilitate a workshop where stakeholders analyze current license allocation and identify cost-saving opportunities.
Example Scenarios:
- Identify users with E5 licenses who only use E3 features
- Find inactive licenses (users who haven't signed in for 90+ days)
- Analyze group-based licensing for optimization opportunities
- Calculate potential savings from rightsizing licenses
Deploy the full stack and monitor license utilization trends over time.
Generate reports showing license assignments for compliance reviews.
Forecast license costs based on current usage patterns and growth projections.
UserPrincipalName,DisplayName,Department,SkuName,SkuId,AssignmentStatus
[email protected],John Doe,Engineering,Office 365 E3,6fd2c87f-b296-42f0-b197-1e91e994b900,Active
[email protected],Jane Smith,Marketing,Office 365 E5,c7df2760-2c81-4ef7-b578-5b5392b571df,Active
- License Utilization Gauge - Percentage of licenses consumed vs. available
- Cost Breakdown by SKU - Visual representation of spend by license type
- Inactive Users Table - Sortable list of users with unused licenses
- Group-Based Licensing Overview - Groups and their assigned licenses
This tool collects:
- β User Principal Names (emails)
- β Display Names
- β Department/Job Title (if available)
- β License assignments
- β Last sign-in dates
β Does NOT collect:
- Email content
- Files or documents
- Personal conversations
- Detailed activity logs beyond sign-in
- π Keep config.json secure - Contains database credentials
- π Use least-privilege accounts - Read-only Graph API permissions
- π Store data locally - Keep CSV exports and databases on secure infrastructure
- π Anonymize for demos - Use provided sample data for demonstrations
- Review your organization's data retention policies
- CSV exports should be treated as sensitive data
- Consider encrypting data at rest
We welcome contributions! See CONTRIBUTING.md for:
- Code style guidelines
- How to submit pull requests
- Feature request process
- Bug report templates
This project is licensed under the MIT License - see LICENSE file for details.
- PostgreSQL - PostgreSQL License
- Grafana - AGPL v3
- Microsoft Graph PowerShell SDK - MIT License
- Documentation: Check the docs/ folder first
- Issues: GitHub Issues
- Discussions: GitHub Discussions
This project was developed from lessons learned conducting Microsoft 365 license optimization tabletop exercises for enterprise organizations. Special thanks to the IT teams who provided feedback and real-world use cases.
- Azure AD Premium P1/P2 license analysis
- Power Platform license tracking
- Cost projection modeling
- Automated remediation workflows
- Multi-tenant support
- REST API for integration
Made with β€οΈ for Microsoft 365 Administrators
Empowering organizations to optimize their M365 licensing investments through data-driven decision making.