PowerShell scripts

Scripts for reporting on, troubleshooting and tidying up Microsoft 365

28 documented PowerShell scripts from day-to-day consulting work — the questions admins ask most often ("which devices stopped syncing?", "who forwards mail outside the company?", "which teams are dead?") turned into repeatable, read-only-by-default tools built on Microsoft Graph and Exchange Online PowerShell V3.

Product

Showing all 28 scripts

Microsoft IntunePowerShell

Export-IntunePolicies.ps1

Exports Intune configuration, compliance, administrative template and platform script policies to JSON for backup and documentation.

Report only229 lines
Microsoft IntunePowerShell

Get-AutopilotDeviceReport.ps1

Windows Autopilot registration health report: profile assignment status, enrollment state and last contact per device.

Report only280 linesCSV report
Microsoft IntunePowerShell

Get-IntuneAppInstallStatus.ps1

Install status overview (installed / failed / pending / not applicable) for every assigned Intune app.

Report only266 linesCSV report
Microsoft IntunePowerShell

Get-IntuneDefenderAVStatus.ps1

Microsoft Defender Antivirus health report for Intune-managed Windows devices.

Report only266 linesCSV report
Microsoft IntunePowerShell

Get-IntunePolicyAssignments.ps1

Builds a "who gets what" assignment matrix for Intune policies and (optionally) apps.

Report only279 linesCSV report
Microsoft IntunePowerShell

Get-IntuneStaleDevices.ps1

Reports Intune managed devices that have not synced for a given number of days and can optionally retire or delete them.

Changes only with -WhatIf-safe switches271 linesCSV report
Microsoft IntunePowerShell

Invoke-IntuneDeviceSync.ps1

Sends a bulk Intune "Sync" remote action to managed devices selected by name, platform, Entra group or all devices.

Changes only with -WhatIf-safe switches266 linesCSV report
Microsoft Entra IDPowerShell

Get-EntraAppCredentialExpiry.ps1

Reports app registration client secrets and certificates that are expired or expiring soon.

Report only290 linesCSV report
Microsoft Entra IDPowerShell

Get-EntraMFARegistrationReport.ps1

Reports the MFA, passwordless and SSPR registration posture of users in Microsoft Entra ID.

Report only239 linesCSV report
Microsoft Entra IDPowerShell

Get-EntraPrivilegedRoleMembers.ps1

Reports who holds Microsoft Entra directory roles, including active assignments and PIM-eligible assignments.

Report only305 linesCSV report
Microsoft Entra IDPowerShell

Get-EntraStaleGuestUsers.ps1

Finds guest accounts that never signed in, have been inactive for a number of days, or never accepted their invitation.

Changes only with -WhatIf-safe switches297 linesCSV report
Microsoft DefenderPowerShell

Get-DefenderAlertsReport.ps1

Reports alerts from Microsoft Defender XDR (unified alerts API) for the last N days.

Report only265 linesCSV report
Microsoft DefenderPowerShell

Get-DefenderIncidentsReport.ps1

Reports Microsoft Defender XDR incidents for triage, including how long each one has been open.

Report only247 linesCSV report
Microsoft DefenderPowerShell

Get-DefenderSecureScore.ps1

Shows the current Microsoft Secure Score and the improvement actions with the largest remaining point gap.

Report only235 linesCSV report
Exchange OnlinePowerShell

Get-EXOExternalForwardingReport.ps1

Finds mail leaving the tenant through mailbox forwarding or inbox rules, and optionally removes it.

Changes only with -WhatIf-safe switches333 linesCSV report
Exchange OnlinePowerShell

Get-EXOMailboxPermissionsReport.ps1

Audits delegated mailbox access: FullAccess, SendAs and SendOnBehalf grants across Exchange Online mailboxes.

Report only251 linesCSV report
Exchange OnlinePowerShell

Get-EXOMailboxSizeReport.ps1

Reports mailbox and archive size, item counts and quota usage for Exchange Online mailboxes.

Report only259 linesCSV report
Microsoft PurviewPowerShell

Export-PurviewDLPPolicies.ps1

Documents Microsoft Purview DLP policies and their rules to CSV and JSON.

Report only290 linesCSV report
Microsoft PurviewPowerShell

Export-PurviewSensitivityLabels.ps1

Documents Microsoft Purview sensitivity labels and label policies to CSV and JSON.

Report only291 linesCSV report
Microsoft PurviewPowerShell

Search-PurviewAuditLog.ps1

Exports unified audit log records reliably, beyond the 5,000-row limit of a single Search-UnifiedAuditLog call.

Report only307 linesCSV report
Teams & SharePointPowerShell

Get-SPOSiteStorageReport.ps1

Reports SharePoint Online storage consumption per site and flags dormant sites, optionally including OneDrive.

Report only340 linesCSV report
Teams & SharePointPowerShell

Get-TeamsGuestAccessReport.ps1

Reports which Microsoft Teams teams contain guest users and which external domains they come from.

Report only268 linesCSV report
Teams & SharePointPowerShell

Get-TeamsInactiveTeams.ps1

Finds Microsoft Teams teams that nobody uses, based on the Teams team activity usage report.

Report only326 linesCSV report
Microsoft 365 tenantPowerShell

Get-M365LicenseReport.ps1

Reports Microsoft 365 license consumption per SKU and, optionally, licensed users whose licenses could be reclaimed.

Report only372 linesCSV report
Microsoft 365 tenantPowerShell

Get-M365ServiceHealthReport.ps1

Reports current Microsoft 365 service incidents and advisories and, optionally, Message Center changes that need action.

Report only330 linesCSV report
ToolsPowerShell

Install-Prerequisites.ps1

Installs or updates the PowerShell modules required by the scripts in this repository.

Changes only with -WhatIf-safe switches128 lines
How they're built

Design principles behind every script

Read-only by default

A script only changes something when you pass an explicit switch such as -RetireDevices or -Remediate. Every change supports -WhatIf and -Confirm.

Least privilege

Each script requests only the Graph scopes or Exchange roles it needs and lists them in its help and in the folder README.

Current tooling

Microsoft Graph PowerShell SDK (v1.0 where possible) and Exchange Online PowerShell V3. No retired AzureAD or MSOnline modules.

Windows PowerShell 5.1 and PowerShell 7

No PowerShell 7-only syntax, so the scripts run wherever your admins already work.

Self-documenting

Get-Help .\Script.ps1 -Full works everywhere. Reports land in .\Reports\ as timestamped CSV files; add -PassThru to keep working with the objects.

Linted in CI

Every script passes PSScriptAnalyzer with the repository's settings before it is published.

Before you run anything: read the script's help (Get-Help .\Script.ps1 -Full), check the permissions it requests, and try it in a test tenant or with -WhatIf first. The scripts are published under the MIT licence — use them, adapt them, and send improvements back through GitHub.

Suggest a topic

Need a script you don't see here?

Tell me which report or clean-up task you'd like automated, and it may become the next addition to the repository.