How to scan Microsoft 365 using CISA ScubaGear integration.

Overview

AuditKit integrates with CISA ScubaGear to scan Microsoft 365 environments.

Why ScubaGear? - Official CISA tool for M365 security assessment - Free and open-source - Comprehensive coverage of 100+ security rules - Trusted by federal agencies

What AuditKit does: Maps ScubaGear results to compliance frameworks (SOC2 and PCI-DSS)

Requirements

System: - Windows 10/11 or Windows Server 2016+ - PowerShell 5.1 or PowerShell 7.2+ - .NET Framework 4.8+

M365 Permissions: - Global Administrator role (or equivalent) - Ability to consent to application permissions

M365 Licenses Required: - Azure AD Premium P1 (minimum) - Microsoft 365 E3 or E5 (recommended)

Quick Start

Step 1: Install ScubaGear (Windows PowerShell)

# Run PowerShell as Administrator

# Install ScubaGear module
Install-Module -Name ScubaGear -Scope CurrentUser

# Verify installation
Get-Module -ListAvailable ScubaGear

Step 2: Run ScubaGear Scan

# Authenticate to M365
# This will open a browser for login
Invoke-SCuBA -ProductNames aad,exo,sharepoint,teams -OutPath ./ScubaResults

# Wait for scan to complete (5-15 minutes)

Step 3: Import Results to AuditKit

ScubaGear names its consolidated output ScubaResults_<uuid>.json, so the glob below picks it up. If a directory holds more than one run, name the file you want explicitly.

# On Linux/macOS/Windows (with AuditKit installed)
./auditkit integrate -source scubagear -file ScubaResults/ScubaResults_*.json

# Generate PDF report
./auditkit integrate -source scubagear -file ScubaResults/ScubaResults_*.json -format pdf -output m365-report.pdf

Detailed Setup Guide

Installing ScubaGear

Option 1: PowerShell Gallery (Recommended)

# Run as Administrator
Install-Module -Name ScubaGear -Scope CurrentUser -Force

# Trust PSGallery if prompted
Set-PSRepository -Name PSGallery -InstallationPolicy Trusted

Option 2: Manual Installation

# Download from GitHub
git clone https://github.com/cisagov/ScubaGear
cd ScubaGear

# Import module
Import-Module ./PowerShell/ScubaGear/ScubaGear.psd1

Verifying Installation

# Check module is installed
Get-Module -ListAvailable ScubaGear

# Check version
(Get-Module -ListAvailable ScubaGear).Version

Running ScubaGear Scans

Scan All Products

# Full M365 scan (recommended)
Invoke-SCuBA -ProductNames aad,exo,sharepoint,teams,powerplatform,defender -OutPath ./ScubaResults

Scan Specific Products

# Entra ID (Azure AD) only
Invoke-SCuBA -ProductNames aad -OutPath ./ScubaResults

# Exchange Online only
Invoke-SCuBA -ProductNames exo -OutPath ./ScubaResults

# SharePoint only
Invoke-SCuBA -ProductNames sharepoint -OutPath ./ScubaResults

# Teams only
Invoke-SCuBA -ProductNames teams -OutPath ./ScubaResults

Available Products

Product ProductName What it scans
Entra ID (Azure AD) aad MFA, Conditional Access, Identity Protection
Exchange Online exo Anti-phishing, DLP, Email encryption
SharePoint sharepoint Sharing policies, DLP, Access controls
Teams teams Meeting security, External access
Power Platform powerplatform DLP policies, Connector governance
Defender defender Safe Links, Safe Attachments, ATP

Authentication

Interactive Authentication (Default)

# Opens browser for login
Invoke-SCuBA -ProductNames aad,exo -OutPath ./ScubaResults

# Login with Global Administrator account
# Accept permissions when prompted

Required permissions: - Global Administrator role - Or equivalent permissions per product

Service Principal Authentication

# Create service principal with required permissions
# Not recommended - interactive auth is simpler

# See ScubaGear docs for service principal setup:
# https://github.com/cisagov/ScubaGear/wiki

Understanding ScubaGear Output

Output Files

After running ScubaGear, you'll find:

ScubaResults/
├── ScubaResults_<uuid>.json    # Main results file (use this with AuditKit)
├── BaselineReports.html        # HTML report
├── IndividualReports/          # Per-product HTML reports
│   ├── AADReport.html
│   ├── EXOReport.html
│   └── ...
└── TestResults/                # Detailed test results

Results Format

{
  "ReportSummary": { "Date": "2026-09-07", "Tenant": "contoso.onmicrosoft.com", "ProductsRun": ["aad"] },
  "Results": {
    "AAD": [
      {
        "Control ID": "MS.AAD.1.1v1",
        "Requirement": "Legacy authentication SHALL be blocked.",
        "Result": "Fail",
        "Criticality": "Shall",
        "Details": "1 conditional access policy found."
      }
    ]
  }
}

Points worth knowing when reading the file yourself:

  • Results is keyed by ScubaGear's baseline names - AAD, EXO, SharePoint, Teams, PowerPlatform, PowerBI - not by the lower-case product arguments you pass to -ProductNames.
  • The policy identifier is in Control ID; Requirement holds the prose.
  • Result is a string: Pass, Fail, Warning, Error, Omitted or Incorrect result. AuditKit scores Pass and Fail; Omitted and Error are reported but excluded from the score, so a policy your team chose not to evaluate does not count against you.
  • Policy ids carry a baseline version suffix (MS.AAD.1.1v1). AuditKit matches on the identifier with or without it.

Importing to AuditKit

Basic Import

# Import ScubaGear results
./auditkit integrate -source scubagear -file ScubaResults/ScubaResults_*.json

Output:

M365 Compliance Scan Results (via ScubaGear)
============================================
Scanned Products: Entra ID, Exchange Online, SharePoint, Teams,
                  Power Platform, Power BI, Defender for Office 365

Compliance Score: 72.4%
Total Rules: 134
Passed: 97
Failed: 37

Framework Mappings:
- SOC2: 134 rules mapped
- PCI-DSS: 134 rules mapped

Critical Issues: 4
High Priority: 8
Medium Priority: 14

Generate Reports

# PDF report
./auditkit integrate -source scubagear -file ScubaResults/ScubaResults_*.json -format pdf -output m365-report.pdf

# JSON output
./auditkit integrate -source scubagear -file ScubaResults/ScubaResults_*.json -format json -output m365-results.json

M365 Service Coverage

Entra ID (Azure AD) - 30 Rules

Authentication & Access: - MFA enforcement - Conditional Access policies - Legacy authentication blocking - Password policies - Guest user restrictions

Identity Protection: - Risk-based sign-in policies - User risk policies - Identity Protection alerts

Administrative Controls: - Privileged Identity Management - Admin MFA requirements - Emergency access accounts

Exchange Online - 40 Rules

Email Security: - Anti-phishing policies - Anti-malware policies - Safe Links configuration - Safe Attachments configuration

Data Loss Prevention: - DLP policies for email - Sensitive information types - Policy tips and notifications

Compliance: - Audit logging - Mailbox auditing - Message encryption

SharePoint - 8 Rules

Sharing & Access: - External sharing settings - Guest access policies - Link sharing defaults

Data Protection: - DLP policies for SharePoint - Information Rights Management - Site access controls

Compliance: - Audit logging - Version history - Information barriers

Teams - 21 Rules

Meeting Security: - Meeting join policies - Lobby settings - Recording policies

External Access: - Guest access settings - External access policies - Federation settings

Data Protection: - DLP policies for Teams - Message retention - eDiscovery settings

Power Platform - 8 Rules

Governance: - DLP policies for connectors - Environment creation restrictions - Power Apps sharing settings

Data Protection: - Connector classification - Cross-tenant isolation - Audit logging

Defender for Office 365 - 19 Rules

Threat Protection: - Safe Links policies - Safe Attachments policies - Anti-phishing policies

Investigation: - Automated investigation - Threat intelligence - Attack simulation training

Troubleshooting

"Module ScubaGear not found"

Cause: ScubaGear not installed

Solution:

Install-Module -Name ScubaGear -Scope CurrentUser -Force

"Access Denied" during scan

Cause: Insufficient permissions

Solution: - Ensure you're logged in as Global Administrator - Or have equivalent permissions for each product - Check Azure AD roles in portal

"Cannot connect to Exchange Online"

Cause: Exchange Online PowerShell not accessible

Solution:

# Install Exchange Online module
Install-Module -Name ExchangeOnlineManagement -Force

# Test connection
Connect-ExchangeOnline -UserPrincipalName admin@yourdomain.com

"ScubaGear scan times out"

Cause: Large tenant with many users/policies

Solution: - Run scans during off-peak hours - Scan products individually instead of all at once - Increase timeout (see ScubaGear docs)

"AuditKit can't parse the ScubaGear results"

Cause: the wrong file was passed, or the output is truncated.

Pass the consolidated ScubaResults_<uuid>.json, not a per-product report from IndividualReports/ and not BaselineReports.html.

Solution:

# Update ScubaGear to latest version
Update-Module -Name ScubaGear

# Re-run scan
Invoke-SCuBA -ProductNames aad,exo -OutPath ./ScubaResults

The import succeeds but reports zero findings

AuditKit only imports policies it has a mapping for - 134 rules across Entra, Exchange Online, SharePoint, Teams, Power Platform, Power BI and Defender. A product you scanned that AuditKit has no mappings for is skipped silently. Check that the products you ran are among those listed under Covered Domains.

Best Practices

1. Run Scans Regularly

# Monthly compliance check
# Create scheduled task or use Task Scheduler

$products = "aad,exo,sharepoint,teams,powerplatform,defender"
Invoke-SCuBA -ProductNames $products -OutPath "C:\ComplianceScans\$(Get-Date -Format 'yyyy-MM-dd')"

2. Use Dedicated Admin Account

Don't use your daily-use account: - Create compliance-scanning@yourdomain.com - Assign Global Reader + required roles - Enable MFA - Use for ScubaGear scans only

3. Document Scan Schedule

For audit purposes: - Run scans before each audit - Store results for 2+ years - Track remediation progress - Re-scan after fixes

4. Combine with AuditKit Cloud Scans

# Complete compliance picture:

# 1. Scan Azure infrastructure
./auditkit scan -provider azure -framework soc2 -format pdf -output azure-report.pdf

# 2. Scan M365 with ScubaGear
Invoke-SCuBA -ProductNames aad,exo,sharepoint,teams -OutPath ./ScubaResults

# 3. Import M365 results
./auditkit integrate -source scubagear -file ScubaResults/ScubaResults_*.json -format pdf -output m365-report.pdf

# Now you have complete Azure + M365 compliance coverage

Security Considerations

What ScubaGear Accesses

Read-only access to: - User accounts and groups - Conditional Access policies - Exchange mailbox settings - SharePoint site settings - Teams configurations - Power Platform environments

Does NOT access: - Email content - Files in SharePoint/OneDrive - Chat messages - User passwords

Audit Logging

All ScubaGear activity is logged in: - Azure AD Audit Logs - Exchange Admin Audit Log - SharePoint Audit Log

Review logs after scans to verify activity.

M365 Compliance Mappings

SOC2 Type II

ScubaGear rules map to SOC 2 criteria; the criteria with the most rules:

  • CC7.2 - 48 rules
  • CC6.6 - 38 rules
  • CC6.2 - 35 rules
  • CC7.1 - 35 rules
  • CC6.3 - 32 rules
  • CC7.3 - 17 rules
  • CC8.1 - 8 rules
  • CC6.1 - 6 rules

PCI-DSS v4.0.1

ScubaGear rules map to PCI DSS requirements:

  • Requirement 1 - 10 rules
  • Requirement 2 - 1 rule
  • Requirement 3 - 18 rules
  • Requirement 5 - 24 rules
  • Requirement 6 - 13 rules
  • Requirement 7 - 48 rules
  • Requirement 8 - 24 rules
  • Requirement 9 - 1 rule
  • Requirement 10 - 56 rules
  • Requirement 12 - 34 rules

CMMC

ScubaGear rules do not currently carry CMMC mappings. M365 findings are mapped to SOC2 and PCI-DSS only; run an Azure scan for CMMC coverage of your Microsoft cloud infrastructure.

Additional Resources

ScubaGear: - GitHub: https://github.com/cisagov/ScubaGear - Documentation: https://github.com/cisagov/ScubaGear/wiki - Issues: https://github.com/cisagov/ScubaGear/issues

Microsoft Security Baselines: - https://learn.microsoft.com/en-us/microsoft-365/security/office-365-security/

CISA M365 Guidance: - https://www.cisa.gov/resources-tools/resources/microsoft-365-security

Next Steps

Start scanning

Full results in about thirty minutes, with a remediation command and a console link on every finding.

Start 14-Day Free Trial

$297/month after the trial. Cancel any time. The Community Edition is free and open source.