I have worked in IT for about 20 years. A lot of that was MSP operations. Today I work as an M365 cloud admin.
I kept writing the same scripts. So I cleaned them up and shared them on GitHub. This toolkit is for Exchange Online admins. It uses PowerShell 7 and ExchangeOnlineManagement v3 with the fast REST-based Get-EXO* cmdlets.
Repo: exchange-online-powershell-toolkit
The problem it solves
Mailboxes collect risk over time. Old permissions stay. Forwarding rules hide in inboxes. Leavers keep paid licenses.
A forwarding rule to an outside address is a classic sign of a compromised account. You want to find those fast.
These scripts give you clear CSV reports. The change scripts support -WhatIf so you can see the result first.
Highlight scripts
Get-InboxRuleForwardingAudit.ps1
Finds mailbox forwarding and inbox rules that forward, redirect or delete mail. Run it for the whole tenant or one user.
./Get-InboxRuleForwardingAudit.ps1
./Get-InboxRuleForwardingAudit.ps1 -Identity user1@contoso.com
Get-SharedMailboxPermissionAudit.ps1
Audits Full Access, Send As and Send on Behalf on shared mailboxes. Good for access reviews.
./Get-SharedMailboxPermissionAudit.ps1
Convert-MailboxToShared.ps1
Converts a leaver's mailbox to shared. It can grant a manager Full Access in the same step.
./Convert-MailboxToShared.ps1 -Identity former.user@contoso.com -GrantFullAccessTo manager@contoso.com -WhatIf
Other scripts cover mailbox inventory, message trace, distribution groups, unlicensed mailboxes and calendar permissions.
How the scripts are built
- PowerShell 7.4 or later.
- Comment-based help on every script. Run
Get-Help ./script.ps1 -Full. - Reports export to CSV.
- Change scripts support
-WhatIfand-Confirm. - Certificate (app-only) or interactive sign-in.
- No secrets in the repo. Examples use
contoso.comand placeholder GUIDs.
Please test in a dev or test tenant first. Read each script before you run it.
My usual workflow
I start with the reports. They are read-only and safe. I open the CSV in Excel and look for anything odd.
Then I pick one fix. I run the change script with -WhatIf and read the output. If it looks right, I run it again for real.
For jobs I repeat, I use a certificate and schedule the script. That way nobody has to remember to run it.
Getting started
Clone the repo:
git clone https://github.com/anthonybuhnerkemper/exchange-online-powershell-toolkit.git
cd exchange-online-powershell-toolkit
Every toolkit ships the same Connect-M365Admin script. Dot-source it, then connect.
# Interactive sign-in
. ./scripts/Connect/Connect-M365Admin.ps1
Connect-M365Admin -Service ExchangeOnline -Interactive -ClientId 00000000-0000-0000-0000-000000000000
# Or app-only with a certificate
$env:M365_TENANT_ID = '00000000-0000-0000-0000-000000000000'
$env:M365_CLIENT_ID = '00000000-0000-0000-0000-000000000000'
$env:M365_CERT_THUMBPRINT = '0000000000000000000000000000000000000000'
Connect-M365Admin -Service ExchangeOnline
Run a report, check the CSV, then call Disconnect-M365Admin when you are done. The README lists the modules and roles each script needs.
More toolkits
I have nine more free toolkits that use the same pattern: graph-powershell7-admin-toolkit, entra-id-powershell-toolkit, sharepoint-online-powershell-toolkit, onedrive-powershell-toolkit, teams-powershell-toolkit, intune-powershell-toolkit, defender-xdr-powershell-toolkit, sentinel-kql-toolkit, purview-compliance-toolkit.
You can find them all on my GitHub profile.
Feedback welcome
Issues, ideas and pull requests are welcome. What would you add? Tell me in the comments.
Top comments (0)