Portfolio  /  Automation & Process Design

Mailbox Consolidation & Migration Pipeline

M365 tenant migration  |  Exchange Online  |  PowerShell  |  Microsoft Graph

PowerShell Exchange Online Microsoft Graph Process Design M365 Groups Mailbox Migration

Background

The Problem


During a large-scale M365 tenant migration 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 migration wave because nothing was formally documented until after the fact.

Before
  • Decisions made verbally during execution
  • No consistent record of what was decided per account
  • Easy to miss accounts or apply the wrong action
  • Mistakes discovered after the fact, requiring manual cleanup
  • No repeatable process; each migration wave was reinvented
After
  • Every account assigned a named plan before any changes run
  • Dropdown options scoped to valid choices per account type
  • Stakeholders review and confirm the plan in Excel
  • Scripts generate a full action list before executing anything
  • Consistent, repeatable process across every migration wave

How It Works

Three-Stage Pipeline


The architecture separates planning, review, and execution into distinct stages with an enforced checkpoint between each. No changes reach the environment until the action plan has been reviewed and confirmed.

Stage 1
Planner Script

Performs automated discovery of all shared mailboxes, distribution lists, M365 groups, and resource accounts across target domains via Exchange Online PowerShell. Generates a structured Excel workbook: 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.

Stage 2
Stamp Script

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 meant to be reviewed and confirmed before proceeding, and shared with stakeholders if needed.

Stage 3
Apply Script

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, consistently and without manual intervention.

Stage 1 Detail

The Planning Workbook


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 requires manual attention before Apply runs.

MailboxReport_Planning.xlsx
Display NamePrimary EmailAccount Type PlanNew Display NameNew EmailNotes
HR Teamhr@legacy.corpShared Mailbox Rename -- Enter New Display Name -- -- Enter New Email --
All Staffallstaff@legacy.corpDistribution List Rename -- Enter New Display Name -- -- Enter New Email --
Marketing Hubmarketing@legacy.corpUnified Group (M365) SP Moving / Mailbox Depreciate+MoveAlias -- Enter New Display Name -- -- Enter New Email -- !! Enter alias target
Legacy Alertsalerts@legacy.corpDistribution List Delete N/AN/A
Info - Downtowninfo-downtown@legacy.corpShared Mailbox Consolidation - Secondary -- Enter New Display Name -- -- Enter New Email -- !! Enter consolidation target in New Email
Noreplynoreply@legacy.corpShared Mailbox No Change Noreply noreply@legacy.corp
Conference Room Aconfroom-a@legacy.corpRoom (Resource) -- Choose Plan -- -- Pending -- -- Pending -- -- Pending --

Sample data with fictional domains. Dropdown options and color coding vary by account type.

Stage 2 Detail

The Action Plan


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.

Phase 0
Manual Warnings
Logged reminders for anything marked "Other", flagged for review and not executed automatically.
Phase 1
Delete
Removes accounts flagged for deletion. Frees their email aliases so they can be reassigned downstream.
Phase 2
Rename
Updates primary email and display name on accounts being kept. The original email is retained as an alias automatically.
Phase 3
Depreciate
For M365 groups with an active SharePoint site: strips all aliases, renames to a depreciated address, preserves the group so the SP site stays accessible through the transition.
Phase 4
Copy Aliases
Adds freed aliases to target accounts. Runs after deletes and depreciations to avoid address conflicts.
Phase 5
Copy Members
Copies group and DL members and owners to targets. Cross-type aware: the operation applied depends on whether the target is a shared mailbox, a group, or a DL.
Phase 6
Copy Permissions
Copies FullAccess, SendAs, and SendOnBehalf permissions from consolidated shared mailboxes to the target account.
Phase 7
Inbox Rules
Creates a labelled folder and inbox rule on the target for each source account. Never merged; each source always gets its own rule and folder, regardless of how many are pointing to the same target.

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.

# Action Plan -- generated by Stamp script  |  Review before running Apply
[Phase 1 – Delete]
DELETE Distribution List
[Phase 2 – Rename]
RENAME
Display"HR Team" → "HR Team - NewCo"
Emailhr@old → hr@new  (original retained as alias)
[Phase 3 – Depreciate]
DEPRECIATE
Emailmarketing-depreciated@old
Display"Marketing Hub - Depreciated"
Aliasesstripped  | SP site preserved via group
[Phase 4 – Copy Aliases]
ADD ALIAS marketing@old, mktg@old
[Phase 6 – Copy Permissions]
COPY PERMS
FullAccessjane@old, bob@old
SendAsjane@old
[Phase 7 – Inbox Rules]
RULE marketing@old → Folder: "Marketing Hub"
RULE info-downtown@old → Folder: "Info - Downtown"
!! 1 account pending plan selection -- resolve before running Apply

Engineering Details

Design Decisions Worth Noting


A few of the non-obvious engineering constraints that shaped the design:

Migration Tooling Sync
Consolidation automatically generates migration tool import rows

When a shared mailbox is marked for consolidation, the scripts handle the Exchange-side work: aliases, permissions, inbox rules. But the mailbox data itself has to move via separate tooling. Rather than managing that list manually, the Stamp script was designed to auto-generate an import row for every Consolidation plan, keeping the migration job queue in sync with the action plan with no extra step.

Cross-Type Resolution
Target-type-aware member and permission copying

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.

SharePoint Preservation
M365 groups with active SP sites depreciated, not deleted

Deleting an M365 group deletes its SharePoint site with it. For groups where SP 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.

My Role

Engineering Approach


I designed this system end to end, including the architecture, decision logic, and operational flow. The pipeline is built around three stages that convert planning decisions into a structured action plan and a synchronized migration job list. That design required building out the account type taxonomy, defining the available plan options per object type, and mapping how each option translates into automated actions downstream. This included determining how conflicts between object types get resolved, how unplanned accounts get surfaced, and how the migration tool job list stays automatically aligned with the generated action plan.

Once the system design was fully specified, I used Claude to assist with writing the PowerShell implementation. The AI received a detailed technical spec describing the expected system behavior and outputs. No tenant data, credentials, or internal configuration details were included in those conversations. A key part of the process was then validating and refining the generated code: reviewing logic paths, testing edge cases, and confirming the scripts behave as intended before anything runs in a live environment.

This workflow lets me move faster without giving up ownership of the design or the result. The automation reduces manual effort, enforces consistent processes, and makes complex migrations repeatable.
Tools & Technologies
PowerShell Exchange Online Microsoft Graph API M365 Groups Entra ID / PIM ImportExcel Module Mailbox Migration Tooling Process Design Change Management Stakeholder Communication