Skip to main content

Admin CLI for Microsoft 365 OneDrive + SharePoint + Mail via Microsoft Graph.

Project description

m365ctl

PyPI CI Python License

An admin CLI for Microsoft 365 — OneDrive, SharePoint, and Exchange Mail — built on Microsoft Graph.

Safe by default: dry-run, plan-file workflow, scope allow-lists, audit log, and undo on every mutation.

Table of contents

Highlights

  • Read-only by default. Mutating verbs require --confirm and are logged.
  • Local catalog. DuckDB mirrors of files and mail enable offline queries.
  • Plan / replay. Bulk operations produce reviewable plan files before execution.
  • Undoable. Every mutation records before/after state for m365ctl undo.
  • Scope guards. allow_drives / allow_mailboxes / deny_paths enforced on every call.
  • App-only auth. Certificate-based auth against your Entra app registration.

Installation

Requires Python 3.11+. Install with uv:

# Standalone CLI (recommended for end users):
uv tool install m365ctl

# Or as a project dependency:
uv add m365ctl

# Or with pipx / pip:
pipx install m365ctl

This installs the m365ctl console script. Verify with m365ctl --help.

For local development from source:

git clone https://github.com/aren13/m365ctl
cd m365ctl
uv sync --all-extras
# The repo's bin/*.sh shims (./bin/od-auth, ./bin/mail-list, ...) are
# convenience aliases for `uv run m365ctl <domain> <verb>`.

Quickstart

  1. Register an Entra app and grant Graph permissions — see docs/setup/azure-app-registration.md.

  2. Generate a client certificate — see docs/setup/certificate-auth.md.

  3. Configure the CLI:

    # Grab the template from the repo or copy from `m365ctl --help` output.
    curl -O https://raw.githubusercontent.com/aren13/m365ctl/main/config.toml.example
    mv config.toml.example config.toml
    # Edit config.toml: tenant id, app id, cert path, allow-lists.
    
  4. Authenticate and verify:

    m365ctl od auth login
    m365ctl od auth whoami
    m365ctl mail whoami
    

Full walkthrough: docs/setup/first-run.md (≤ 20 minutes from install to whoami).

Features

OneDrive and SharePoint

Capability Commands
Catalog mirror od-catalog-refresh, od-catalog-status
Search od-search (server and local)
Inventory od-inventory (top-by-size, top-by-age, dups)
File operations od-move, od-rename, od-copy
Sensitivity od-label
Sharing audit od-audit-sharing
Recycle bin od-clean, od-delete
Download od-download (bulk + resumable)

Mail

Capability Commands
Read mail-list, mail-get, mail-read, mail-search
Folders / labels mail-folders, mail-categories, mail-categorize
Compose mail-draft, mail-send, mail-reply, mail-forward
Move / flag mail-move, mail-copy, mail-flag, mail-focus
Inbox rules mail-rules (create, update, delete, import, export)
Mailbox settings mail-settings, mail-ooo, mail-signature
Triage DSL mail-triage (YAML rules over local catalog)
Catalog mail-catalog-refresh, mail-catalog-status
Export mail-export (EML, MBOX, attachments, full mailbox)
Hard delete mail-clean, mail-empty (triple-gated)
Delegation mail-delegate, --mailbox shared:<addr> routing
Send-as mail-sendas (app-only, fully audited)
Scheduled send mail-send --schedule-at <iso>
Convenience verbs mail-digest, mail-archive, mail-snooze, mail-top-senders, mail-size-report, mail-unsubscribe

Each verb supports --help. See docs/mail/convenience-commands.md for the convenience-verb reference.

Safety model

Layer Behavior
Dry-run default Mutating verbs print a plan and exit unless --confirm is passed.
Plan files Bulk operations write a plan file that can be reviewed before --replay.
Scope allow-lists allow_drives / allow_mailboxes gate every API call; deny_paths / deny_folders are absolute.
Audit log Each mutation records a before/after block to a tamper-resistant log.
Undo m365ctl undo <op-id> (or od-undo / mail-undo) replays the inverse using the audit record.
Hard-delete gate Irreversible deletes require --confirm, a TTY-typed phrase, and an extra escalation for large ops.

Configuration

config.toml controls auth, scopes, paths, and feature flags. Start from config.toml.example:

[auth]
tenant_id   = "..."
client_id   = "..."
cert_path   = "~/.m365ctl/cert.pem"

[scope]
allow_drives    = ["..."]
allow_mailboxes = ["user@example.com"]
deny_paths      = ["/Confidential"]

[mail]
schedule_send_enabled = false

Catalog files, plan files, and the audit log default to cache/, plans/, and logs/ under the project root — override per config.toml.

Documentation

Topic Link
Azure app registration docs/setup/azure-app-registration.md
Certificate-based auth docs/setup/certificate-auth.md
First-run walkthrough docs/setup/first-run.md
PnP PowerShell prerequisites docs/ops/pnp-powershell-setup.md
Mail convenience verbs docs/mail/convenience-commands.md
Roadmap docs/roadmap.md
Changelog CHANGELOG.md
Contributing CONTRIBUTING.md

Contributing

Issues and pull requests welcome. Before opening a PR, please read CONTRIBUTING.md and run the test suite:

uv run pytest
uv run ruff check .
uv run mypy src

License

Apache-2.0. See LICENSE.

Disclaimer

This is an independent open-source project. Not affiliated with, endorsed by, or supported by Microsoft. "Microsoft 365", "OneDrive", "SharePoint", and "Exchange" are trademarks of Microsoft Corporation.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

m365ctl-1.13.0.tar.gz (398.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

m365ctl-1.13.0-py3-none-any.whl (262.6 kB view details)

Uploaded Python 3

File details

Details for the file m365ctl-1.13.0.tar.gz.

File metadata

  • Download URL: m365ctl-1.13.0.tar.gz
  • Upload date:
  • Size: 398.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for m365ctl-1.13.0.tar.gz
Algorithm Hash digest
SHA256 75e72ad5e141ca2606760c678a7495a73f40ff83cf0d978db9cbd38cbd04a710
MD5 bdbed54f3ac1b3e136d3d3150e373716
BLAKE2b-256 c35060ef58ea0e9ebaa0a68affe7d8b6ed05f7a7cdee5c6f5accc6db3bd9b24e

See more details on using hashes here.

Provenance

The following attestation bundles were made for m365ctl-1.13.0.tar.gz:

Publisher: release.yml on aren13/m365ctl

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file m365ctl-1.13.0-py3-none-any.whl.

File metadata

  • Download URL: m365ctl-1.13.0-py3-none-any.whl
  • Upload date:
  • Size: 262.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for m365ctl-1.13.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f91a41fb4fa00533c2af60f7f5fd8bd6b1d9b70b3808ea8d1184ba238305818a
MD5 abd344676db338be44186c649b98852b
BLAKE2b-256 ca79e7c057413634a7996e087038515ad1e34c480bab2aee6bcf05e083c50795

See more details on using hashes here.

Provenance

The following attestation bundles were made for m365ctl-1.13.0-py3-none-any.whl:

Publisher: release.yml on aren13/m365ctl

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page