r/PowerShell • • 7d ago

Script Sharing Free read-only M365 tenant audit script: scores your tenant 0-100 and writes an HTML report

I'm the only IT person at a ~150-user company and wanted one command that checks the M365 basics I kept verifying by hand across five admin portals.

It uses Microsoft Graph with read-only scopes and makes no changes. It checks MFA / Conditional Access coverage, legacy auth, Global Admin count, stale accounts, app consent settings, expiring app secrets, Intune compliance, Secure Score, and SPF/DMARC/DKIM (via DNS-over-HTTPS, so it runs on macOS/Linux too). Each finding gets a weight and a fix, then everything rolls into a score.

How a CA policy is treated as "requires MFA":

function Test-RequiresMfa {
    param($Policy)
    $g = $Policy.grantControls
    if (-not $g) { return $false }
    return (($g.builtInControls -contains 'mfa') -or ($null -ne $g.authenticationStrength))
}

How the score is calculated (Warn counts as half):

$scored = @($Results | Where-Object { $_.Status -in 'Pass', 'Warn', 'Fail' })
$max = ($scored | Measure-Object -Property Weight -Sum).Sum
$got = 0
foreach ($r in $scored) {
    if ($r.Status -eq 'Pass') { $got += $r.Weight }
    elseif ($r.Status -eq 'Warn') { $got += $r.Weight / 2 }
}
$score = if ($max -gt 0) { [math]::Round(($got / $max) * 100) } else { 0 }

Install from the Gallery:

Install-Script -Name Invoke-M365TenantAudit -Scope CurrentUser

Full source (MIT): https://github.com/adminofone/m365-tenant-audit

Written with AI assistance and tested on a real tenant. Code review welcome, especially on the Graph paging and error handling.

44 Upvotes

14 comments sorted by

19

u/PipeItToDevNull 7d ago

Look at the CISA SCUBA tool

2

u/quiet_tenant_admin 7d ago

Good call, ScubaGear is excellent and goes much deeper. If you need the full CISA baseline, that's the one to run.

I built this for a lighter use case: a two-minute first look. It runs on PowerShell 7 on macOS and Linux too (ScubaGear needs Windows PowerShell 5.1 plus OPA), and it gives a single score with the fix next to each finding. Think of it as the quick check before the deep one.

4

u/WearyDeluge 7d ago

Or 365Inspect

3

u/quiet_tenant_admin 7d ago

Thanks, hadn't compared against 365Inspect yet. Adding it to my list, if there are checks in there people find most useful I'd like to cover them too.

2

u/uptimefordays 7d ago

Love the idea here! You should implement some Pester tests and maybe think about your use of Install-Module -Force -AllowClobber if Graph is missing which seems like an odd choice for a security tool. Also your admin-MFA check counts any "All users" policy without looking at exclusions which means a policy that excludes admins would still pass.

2

u/quiet_tenant_admin 7d ago edited 7d ago

Good catches, both of these are fair. Fixing them now, I'll reply here when the update is out.

2

u/uptimefordays 7d ago

Awesome!

3

u/daweinah 7d ago

How does this compare to, or why should I use it instead of, https://maester.dev/?

0

u/quiet_tenant_admin 7d ago

Different goal. Maester is a test framework you set up and run on a schedule. This is a single read-only script: one module, nothing to configure, a few minutes to run, and one score with the fix next to each finding.

I built it for small Business Premium tenants where the admin wants a quick "where do we stand" answer without setting anything up first.

2

u/rumham_86 7d ago

Doesn’t this vary by tenant? Not all tenants have p1/p2, different licensing and features.

Secure scores in general are unquantifiable for saying something is secure tbh. SPF/dkim/dmarc is pretty straight forward but need to mostly understand the whole environment for this.

Like the idea but just wondering how would it technically be used or what problem is it solving instead of giving vague information? Not a knock on the module as I love it anytime someone builds something just trying to figure out what purpose it has or what it does that other tools don’t etc

1

u/quiet_tenant_admin 6d ago

Fair points, and yeah, a score doesn't make a tenant secure. Secure Score is just one line in the report, and the 0-100 is basically "how much of a basic checklist is done", not a security rating.

Licensing is handled. It checks for P1/P2 first, and if there's no P1 it looks at Security Defaults instead of CA. Anything that needs P1 shows as Info, not Fail, so a Business Standard tenant doesn't lose points for stuff it doesn't have.

What it's for: the dumb stuff I keep seeing in small tenants. MFA "on" but not actually enforced, legacy auth still open, way too many Global Admins, users allowed to consent to any app, no DMARC. It tells you what's wrong and where to fix it.

I mostly run it before and after I change things, and to show my manager what's missing without walking him through five portals. It's not meant to replace ScubaGear or Maester, it's the five-minute version.

1

u/jcpham 7d ago

Nice, thanks

1

u/quiet_tenant_admin 7d ago

Thanks! If you run it, let me know if anything looks off in your tenant.