Portfolio / Automation & Process Engineering
PowerShell | Exchange Online | Microsoft Graph | M365 Tenant Consolidation
Background
During a large-scale M365 tenant consolidation spanning 200+ locations, hundreds of shared mailboxes, distribution lists, M365 groups, and resource accounts needed to be consolidated, renamed, or decommissioned across domain transitions. Each object type required a different disposition: rename it, delete it, consolidate it into another account, move its email aliases elsewhere, or leave it alone.
The original process relied on decisions made verbally or from memory during execution. That led to inconsistencies, missed accounts, and mistakes that required manual remediation. The same decisions got relitigated across every consolidation wave because nothing was formally documented until after the fact. The answer was not better documentation after the fact. It was automation that enforced the process before anything ran.
Architecture
The pipeline separates discovery, planning, and execution into three distinct stages with an enforced human review checkpoint between planning and execution. No changes reach the environment until the full action plan has been reviewed and confirmed. Each stage is a standalone PowerShell script that can be rerun independently.
Connects to Exchange Online and performs automated discovery of all shared mailboxes, distribution lists, M365 groups, and resource accounts across target domains. Outputs a structured Excel workbook with a full inventory sheet and a planning sheet with per-account-type dropdown menus and formula-driven columns that auto-populate based on the selected plan.
Reads the completed planning sheet and translates every plan selection into a structured, human-readable action list showing exactly what will happen to each account before anything is touched. Output is reviewed and confirmed by stakeholders before proceeding. Also auto-generates migration tool import rows for any consolidation plans.
Executes the approved action plan idempotently, in a defined phase order. Renames accounts, updates email addresses, moves aliases, copies permissions, handles consolidations, creates inbox rules, and removes accounts marked for deletion, without manual intervention at any step.
Stage 1 Detail
A key design decision was that dropdown options are scoped to the account type. A shared mailbox has different valid plans than a distribution list or an M365 group, so the dropdown only shows options that are actually applicable. Once a plan is selected, the New Display Name, New Email, and Notes columns auto-populate with either a calculated value, a placeholder prompting for remaining input, or a warning flagging something that needs manual attention before Apply runs.
| Display Name | Primary Email | Account Type | Plan | New Display Name | New Email | Notes |
|---|---|---|---|---|---|---|
| HR Team | hr@legacy.corp | Shared Mailbox | Rename | -- Enter New Display Name -- | -- Enter New Email -- | |
| All Staff | allstaff@legacy.corp | Distribution List | Rename | -- Enter New Display Name -- | -- Enter New Email -- | |
| Marketing Hub | marketing@legacy.corp | Unified Group (M365) | SP Moving / Mailbox Depreciate+MoveAlias | -- Enter New Display Name -- | -- Enter New Email -- | !! Enter alias target |
| Legacy Alerts | alerts@legacy.corp | Distribution List | Delete | N/A | N/A | |
| Info - Downtown | info-downtown@legacy.corp | Shared Mailbox | Consolidation - Secondary | -- Enter New Display Name -- | -- Enter New Email -- | !! Enter consolidation target in New Email |
| Noreply | noreply@legacy.corp | Shared Mailbox | No Change | Noreply | noreply@legacy.corp | |
| Conference Room A | confroom-a@legacy.corp | Room (Resource) | -- Choose Plan -- | -- Pending -- | -- Pending -- | -- Pending -- |
Sample data with fictional domains. Dropdown options and color coding vary by account type.
Stage 2 Detail
Before any change runs, the Stamp script reads the completed planning sheet and produces a structured action list broken into numbered phases. The phase order is intentional: aliases have to be freed by deletes and depreciations before they can be copied to target accounts, and inbox rules are always created last so the folder structure is in place when they run.
When multiple source accounts target the same destination with the same action type, the Stamp script merges them into a single row with comma-delimited values, keeping the action plan clean and reducing redundant operations at apply time. Inbox rules are the deliberate exception to this.
Engineering Details
A few non-obvious engineering constraints shaped the design:
When a shared mailbox is marked for consolidation, the scripts handle the Exchange-side work: aliases, permissions, inbox rules. The mailbox data itself has to move via separate tooling. Rather than managing that list manually, the Stamp script auto-generates an import row for every Consolidation plan, keeping the migration job queue in sync with the action plan with no extra step.
When copying members or owners to a target account, the correct operation depends on what type of object the target is. SMB target: GrantFullAccess + GrantSendAs. Group target: AddMember + AddOwner. DL target: AddMember + SetManagedBy. The scripts resolve target type at runtime and apply the right operation automatically, with no manual adjustment per account.
Deleting an M365 group deletes its SharePoint site with it. For groups where SharePoint content needs to stay accessible, the depreciation plans keep the group alive in a stripped state: aliases removed, email and display name updated to signal deprecated status, so the SharePoint site remains reachable through the transition period without blocking alias reassignment.
Takeaways
Migrations fail at the planning layer, not the execution layer. This pipeline addresses that directly by encoding the decision logic into the tooling itself rather than relying on human consistency at runtime.
The pipeline does not just automate tasks. It enforces a specific order of operations and gates execution behind a human-reviewed plan, so the process is consistent regardless of who runs it or when.
The Apply script is designed to be rerun safely. It resolves the current state of each account at runtime and only makes changes that are still needed, so partial runs and reruns do not produce duplicate or conflicting changes.
The planning workbook and action plan output are designed to be handed to stakeholders for review, not just used internally. Non-technical decision makers can approve or flag accounts without needing to understand the underlying scripts.
The pipeline was built for a 200+ location consolidation with multiple waves. Rerunning Stage 1 on a new domain set produces a fresh planning workbook in the same format, so the same review and execution process applies every time without rebuilding anything.
My Role