Portfolio  /  Automation & Process Engineering

M365 Consolidation Automation Pipeline

PowerShell  |  Exchange Online  |  Microsoft Graph  |  M365 Tenant Consolidation

PowerShell Automation Exchange Online Microsoft Graph M365 Groups Process Engineering Tenant Consolidation Change Management

Background

The Problem


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.

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

Architecture

Three-Stage Automation Pipeline


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.

Stage 1
Planner Script

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.

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 reviewed and confirmed by stakeholders before proceeding. Also auto-generates migration tool import rows for any consolidation plans.

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, without manual intervention at any step.

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 needs 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. Surfaces edge cases before execution begins.
Phase 1
Delete
Removes accounts flagged for deletion. Frees their email aliases so they can be reassigned downstream without conflicts.
Phase 2
Rename
Updates primary email and display name on accounts being kept. The original email address 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 SharePoint site stays accessible through the transition period.
Phase 4
Copy Aliases
Adds freed aliases to target accounts. Runs after deletes and depreciations to guarantee no address conflicts exist at copy time.
Phase 5
Copy Members
Copies group and DL members and owners to target accounts. Cross-type aware: the correct operation is resolved at runtime based on whether the target is a shared mailbox, group, or distribution list.
Phase 6
Copy Permissions
Copies FullAccess, SendAs, and SendOnBehalf permissions from consolidated shared mailboxes to the target account.
Phase 7
Inbox Rules
Creates a labeled 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 non-obvious engineering constraints 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. 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.

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 SharePoint sites depreciated, not deleted

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

What This Demonstrates


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.

Automation that enforces process

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.

Idempotent, safe execution

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.

Stakeholder-facing output

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.

Reusable across migration waves

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

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 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 ran 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 consolidations repeatable at scale.
Tools & Technologies
PowerShell Exchange Online Microsoft Graph API M365 Groups Entra ID ImportExcel Module M365 Consolidation Tooling Process Engineering Change Management Stakeholder Communication