This repository contains a PowerShell utility, Copy-GraphMailboxItems.ps1, for copying Exchange Online mailbox content by using Microsoft Graph mailbox import/export APIs.
The script supports:
- same-tenant and cross-tenant copies
.env-driven defaults with command-line override- preflight validation
- confirmation with
-Forcebypass - overlay mailbox copies
- special handling for Calendar, Contacts, Tasks, and Notes
- include/exclude folder filtering
- date-range filtering
Copy-GraphMailboxItems.ps1Main implementation. Most changes belong here.README.mdUser-facing behavior, examples, and parameter documentation.SETUP.mdPrerequisites, permissions, tenant/app setup, and certificate requirements..env.exampleTemplate for local runtime defaults..envLocal machine configuration. Do not commit secrets from this file.
- Keep the script PowerShell-first. Do not replace major logic with external dependencies unless clearly necessary.
- Preserve existing operator ergonomics:
-WhatIf-Verbose-PreflightOnly- confirmation summary
-Force
- Treat the confirmation, preflight, and
.envbehaviors as core features, not optional extras. - Prefer additive, low-risk changes over broad rewrites.
- Keep comments sparse and useful.
- Command-line parameters must continue to override
.envvalues. .env.exampleshould stay safe to commit and should not contain live secrets..envshould remain git-ignored.- If new settings are added to the script, update:
.env.exampleREADME.md- confirmation summary if the setting materially affects behavior
When modifying the script, preserve these behaviors unless explicitly changing them on purpose:
Journal,Conversation History, andRSS Subscriptionsare always excluded.IncludeFolderPathandExcludeFolderPathare mutually exclusive.- Empty folders are skipped by default unless
-CopyEmptyFoldersis used. - Special roots:
CalendarContactsTasksNotesmust retain their current direct-import and subfolder behaviors.
- Overlay mode must not create a wrapper folder for source root copies.
- Preflight must fail early on ambiguous duplicate target folders.
- Confirmation must summarize the operation before real execution unless bypassed with
-Force.
After changing behavior, do as many of these as apply:
- Run a PowerShell parse check.
- Run a
-PreflightOnlyvalidation for the affected scenario. - Use
-WhatIffor copy-path changes when possible. - Update docs if parameters, defaults, or examples changed.
Simple parse check:
$null = [System.Management.Automation.Language.Parser]::ParseFile(
'C:\_repos\GraphMailboxSync\Copy-GraphMailboxItems.ps1',
[ref]$null,
[ref]$null
)- For auth or tenant changes:
update both
README.mdandSETUP.md. - For parameter changes:
update the param block,
.envloading,.env.example, and docs together. - For target mapping or folder traversal changes: review overlay mode, special-folder routing, and preflight ambiguity checks together.
- For exclusion logic changes: document whether the match is type-based or display-name-based.
- Commit only intended repo files.
- Do not commit
.env. - Keep commit messages short and descriptive.