Skip to content

Open-source Microsoft 365 license analysis and optimization toolkit for tabletop exercises and strategic planning. Features automated data collection, PostgreSQL storage, Grafana dashboards, and comprehensive reporting for license optimization.

License

Notifications You must be signed in to change notification settings

MSSecCSA/M365LicenseAnalyzer-Public

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

1 Commit
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

M365 License Analyzer

Open-source Microsoft 365 license analysis and optimization tool for Tabletop Exercises and strategic planning

License: MIT PowerShell Docker

🎯 What is This?

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.

Key Features

  • βœ… 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

πŸš€ Quick Start

Option 1: Standalone (CSV Reports Only)

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.csv

Option 2: Full Stack (Docker + Grafana)

Best 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)

πŸ“‹ Prerequisites

Required

  • PowerShell 5.1+ (Windows) or PowerShell 7+ (Cross-platform)
  • Microsoft Graph PowerShell SDK
    Install-Module Microsoft.Graph -Scope CurrentUser

Optional (for Full Stack)

Microsoft 365 Permissions

Your account needs these Microsoft Graph API permissions:

  • User.Read.All
  • Organization.Read.All
  • Directory.Read.All

Note: Global Reader or License Administrator roles typically have these permissions.


πŸ“– Documentation

Core Guides

Advanced Topics


πŸ—οΈ Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    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                              β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸŽ“ Use Cases

1. License Optimization Tabletop Exercise

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

2. Ongoing License Monitoring

Deploy the full stack and monitor license utilization trends over time.

3. Compliance Auditing

Generate reports showing license assignments for compliance reviews.

4. Budget Planning

Forecast license costs based on current usage patterns and growth projections.


πŸ“Š Sample Outputs

CSV Report Example

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

Grafana Dashboard Preview

  • 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

πŸ”’ Security & Privacy

Data Sensitivity

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

Best Practices

  • πŸ” 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

Data Retention

  • Review your organization's data retention policies
  • CSV exports should be treated as sensitive data
  • Consider encrypting data at rest

🀝 Contributing

We welcome contributions! See CONTRIBUTING.md for:

  • Code style guidelines
  • How to submit pull requests
  • Feature request process
  • Bug report templates

πŸ“„ License

This project is licensed under the MIT License - see LICENSE file for details.

Third-Party Licenses

  • PostgreSQL - PostgreSQL License
  • Grafana - AGPL v3
  • Microsoft Graph PowerShell SDK - MIT License

πŸ™‹ Support & Community

Getting Help

Acknowledgments

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.


πŸ—ΊοΈ Roadmap

  • Azure AD Premium P1/P2 license analysis
  • Power Platform license tracking
  • Cost projection modeling
  • Automated remediation workflows
  • Multi-tenant support
  • REST API for integration

⚑ Quick Links


Made with ❀️ for Microsoft 365 Administrators

Empowering organizations to optimize their M365 licensing investments through data-driven decision making.

About

Open-source Microsoft 365 license analysis and optimization toolkit for tabletop exercises and strategic planning. Features automated data collection, PostgreSQL storage, Grafana dashboards, and comprehensive reporting for license optimization.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published