M365 Toolbox is a web-based console for approved Microsoft 365 PowerShell operations. It combines a React frontend, an Express API, a Redis-backed BullMQ queue, a PostgreSQL-backed run store, a dedicated PowerShell worker, and a toolbox-native script catalog so admins can launch reports and response workflows from the browser, authenticate with Microsoft device code, and review results without leaving the app.
- Presents a categorized script catalog for Microsoft 365 operations
- Runs allowlisted PowerShell scripts through a controlled backend wrapper
- Prompts for Microsoft device-code sign-in when a script requires authentication
- Tracks run status, command details, stdout, stderr, exit code, and artifacts
- Renders HTML reports inline in the UI and supports direct download
- Stores favorites in the browser for faster access to common workflows
The current catalog includes 59 toolbox-native scripts across categories such as Identity, Exchange, Security, SharePoint, Teams, Reporting, Licensing, Devices, Operations, Collaboration, and Incident Response.
backend/Express API, queue integration, run tracking, artifact endpoints, and worker health reportingfrontend/React/Vite UI with the resizable sidebar, category icons, dark mode, favorites, dashboard shortcuts, run details, and inline report previewscripts/Toolbox-native PowerShell scripts, the script wrapper, and shared report helpersscripts/catalog/JSON catalog files that define script metadata, fields, risk, and runner behavioroutput/Generated report artifacts written by backend runsdocker-compose.ymlStarts PostgreSQL, Redis, the backend, the PowerShell worker, and the frontend togetherdocker-compose.prod.ymlProduction-oriented Docker Compose deployment for self-hostingdocker-compose.coolify.ymlCompose variant aimed at Coolify or Portainer-style deployments
- Resizable left sidebar for the script catalog
- Search and category browsing in the catalog
- Category icons in the sidebar for faster scanning
- Read-only versus remediation mode labeling and filtering
- Favorites toggle and favorites-only filtering
- Dark mode toggle
- Better dashboard home screen with quick stats and shortcuts
- Recent favorites and most-used shortcuts on the dashboard
- Persistent run history in the UI
- Queue-aware execution with queued run status
- Run cancellation from the UI
- Structured run logs, timestamps, and clearer run-state feedback
- Artifact browser for HTML, CSV, XLSX, text, and log downloads
- ZIP bundle download for full run artifact packages
- Inline HTML report preview after successful runs, with the report brought into focus automatically
- Device-code modal that surfaces the sign-in code, copy action, and login URL
- Approval confirmation prompt for remediation workflows
- Action profiles and high-impact action guidance for the compromised-account workflow
- Backend status view for Redis, queue, worker heartbeat, script mount, and output path readiness
- GitHub repository link in the sidebar footer
Core workflows and reporting:
scripts/M365-CompromisedAccountRemediation.ps1Contains and investigates compromised accounts with review-only and containment profiles, recent sign-in review, optional delegate cleanup and protocol lock-down, and a richer incident dashboard.scripts/M365-MfaReport.ps1Builds a tenant-wide MFA coverage report with admin-risk visibility.scripts/M365-UsageReport.ps1Creates OneDrive, SharePoint, and mailbox usage dashboards.scripts/M365-LicensingReport.ps1Reviews subscribed SKUs, assigned licenses, and unlicensed users.scripts/M365-GuestAccessReport.ps1Audits guest accounts, invitation state, stale guests, and external domains.scripts/M365-ConditionalAccessReport.ps1Summarizes Conditional Access policies, state, scope, and grant controls.scripts/M365-MailForwardingAudit.ps1Finds mailbox forwarding and inbox rules that redirect mail.scripts/M365-SharedMailboxReport.ps1Reviews shared mailboxes, forwarding, visibility, and delegate counts.scripts/M365-ImapMigrationPreflight.ps1Validates mounted IMAP migration CSV readiness, Exchange Online sign-in, and source IMAP endpoint availability.scripts/M365-ImapMigrationBatch.ps1Creates or reuses an Exchange Online IMAP migration endpoint, creates a migration batch from CSVData, and can optionally start it.scripts/M365-ImapMigrationStatus.ps1Exports current Exchange Online migration batch summary and per-user migration status.scripts/M365-SignInRiskReport.ps1Shows risky users and detections when Identity Protection data is licensed and available.scripts/M365-TeamsExternalAccessReport.ps1Reviews Teams guest exposure, ownership gaps, and external membership.scripts/M365-SharePointSharingReport.ps1Combines SharePoint tenant sharing settings with site usage inventory.scripts/M365-SecureScoreSnapshot.ps1Captures the latest Secure Score snapshot and top improvement controls.scripts/M365-AdminRoleAudit.ps1Audits privileged role assignments and MFA hygiene for admin accounts.
Audit, hygiene, and operations reports:
scripts/M365-InactiveUsersReport.ps1Identifies inactive accounts and likely license-reclaim candidates.scripts/M365-AppConsentAudit.ps1Reviews enterprise app consent grants and high-privilege delegated scopes.scripts/M365-MailboxPermissionAudit.ps1Audits Full Access and Send As delegation across mailboxes.scripts/M365-ExternalSharingLinksReport.ps1Reviews SharePoint external sharing posture and site-level sharing link counts.scripts/M365-DistributionGroupAudit.ps1Audits distribution group ownership, membership, and external sender exposure.scripts/M365-ServiceHealthSnapshot.ps1Captures current Microsoft 365 service health and active advisories.scripts/M365-AuthenticationPolicyReport.ps1Reviews security defaults and authentication methods policy posture.scripts/M365-PrivilegedAppAudit.ps1Inventories service principal credentials and non-human identity exposure.scripts/M365-DkimDmarcReport.ps1Reviews accepted domains for DKIM signing and DMARC presence.scripts/M365-GroupLifecycleReport.ps1Audits Microsoft 365 group ownership, renewal activity, and lifecycle hygiene.
Latest additions:
scripts/M365-CAPolicyCoverageReport.ps1Maps Conditional Access inclusion and exclusion coverage across users, groups, guests, and apps.scripts/M365-LegacyAuthExposureReport.ps1Surfaces recent legacy-authentication sign-ins and affected users.scripts/M365-PIMRoleActivationReport.ps1Reviews active and eligible privileged role schedule instances from Entra ID.scripts/M365-DeviceComplianceSnapshot.ps1Summarizes Intune-managed device compliance, ownership, and platform mix.scripts/M365-B2BDirectConnectReport.ps1Reviews cross-tenant access defaults and B2B direct connect posture.scripts/M365-MailTransportRulesAudit.ps1Audits Exchange Online mail transport rules and test/audit mode coverage.scripts/M365-DefenderIncidentSnapshot.ps1Captures current Defender incidents, severity, and status.scripts/M365-PrivilegedGroupAudit.ps1Reviews sensitive groups for owner gaps and membership exposure.scripts/M365-PasswordResetReadinessReport.ps1Estimates self-service password reset readiness from registered auth methods.scripts/M365-OneDriveExternalSharingReport.ps1Reviews OneDrive usage and highlights large or highly active personal sites.scripts/M365-MFARegistrationCampaignReport.ps1Reviews MFA registration campaign settings and rollout posture.scripts/M365-EnterpriseAppsInventory.ps1Inventories enterprise applications for ownership, visibility, and risk review.scripts/M365-GuestInvitationFailures.ps1Surfaces guest invitation issues and onboarding failures for follow-up.scripts/M365-MailboxAutoReplyAudit.ps1Reviews mailbox automatic replies for external exposure and operational awareness.scripts/M365-CalendarSharingAudit.ps1Audits mailbox calendar sharing posture and external visibility.scripts/M365-RoleEligibleAssignmentsReport.ps1Reviews eligible privileged role assignments and standing access exposure.scripts/M365-AnonymousLinkExposureReport.ps1Highlights anonymous sharing links and externally accessible content exposure.scripts/M365-TeamsOwnershipAudit.ps1Reviews Microsoft Teams ownership gaps and governance hygiene.scripts/M365-AppCredentialExpiryReport.ps1Finds expiring or stale application credentials that need rotation.scripts/M365-MailflowConnectorAudit.ps1Reviews inbound and outbound Exchange Online connectors, relay paths, and TLS posture.scripts/M365-BreakGlassAccountAudit.ps1Reviews emergency access accounts for privilege, MFA, and recent sign-in visibility.scripts/M365-ImpossibleTravelReview.ps1Highlights rapid country-to-country sign-in changes for the same user.scripts/M365-MailboxLoginAnomalyReview.ps1Reviews mailbox-related sign-ins with suspicious client, failure, or access patterns.scripts/M365-ExternalTenantTrustReview.ps1Summarizes cross-tenant partner trust settings and guest domain concentration.scripts/M365-PrivilegedUserSignInReview.ps1Reviews recent sign-in visibility for privileged users across directory roles.scripts/M365-InboxRuleThreatHunt.ps1Hunts for suspicious inbox rules that forward, redirect, hide, or delete messages.scripts/M365-ConditionalAccessGapReview.ps1Highlights Conditional Access policies with exclusions, missing controls, or weak enforcement.scripts/M365-MFAExclusionAudit.ps1Audits MFA-enforcing policies that still exclude users, groups, or roles.scripts/M365-DormantAdminAccountReview.ps1Finds privileged accounts with little or no recent sign-in activity.scripts/M365-SharedMailboxAbuseReview.ps1Reviews shared mailboxes for forwarding, risky delegates, and inbox rule abuse signals.scripts/M365-TransportRuleThreatHunt.ps1Flags transport rules with redirect, bypass, delete, or routing threat signals.scripts/M365-BreakGlassAccountHardeningReview.ps1Reviews likely break-glass accounts for MFA, state, and hardening posture.scripts/M365-OAuthAppRiskReview.ps1Highlights OAuth-enabled apps with delegated grants, risky scopes, and credential risk.
The catalog loader lives in backend/src/data/scripts.js, the catalog source files live in scripts/catalog, and the PowerShell entry scripts live in scripts.
The backend loads script metadata from the JSON catalog, accepts validated run requests, persists queued run records in PostgreSQL, and hands execution to BullMQ. A separate PowerShell worker container reads queued jobs, launches scripts/Invoke-ToolboxScript.ps1, captures structured events and artifacts, and writes incremental logs, artifacts, approvals, and result metadata back to PostgreSQL while keeping report files in output/.
The backend tracks:
- selected script id
- generated command line
- stdout
- stderr
- structured log entries
- run status
- queued, running, canceling, completed, failed, canceled, and interrupted lifecycle states
- exit code
- timestamps
- artifact inventory for exported files
The frontend Settings page can store reusable company mappings in the browser. Add a Company Name and a Tenant ID or Domain, then type either the company name, tenant id, or domain in a script tenant field to resolve it before launch.
Company mappings can be imported or exported as CSV. Use two columns:
Company Name,Tenant ID or Domain
Contoso,contoso.onmicrosoft.com
Fabrikam,fabrikam.com
Northwind,00000000-0000-0000-0000-000000000000The header row is optional but recommended. If a company name contains a comma, wrap it in quotes, for example "Contoso, Ltd.",contoso.onmicrosoft.com.
High-level flow:
Frontend
-> API backend
-> BullMQ / Redis
-> PowerShell worker
-> Artifacts + PostgreSQL run store
Runtime controls available through environment variables:
MAX_CONCURRENT_RUNSLimits how many worker jobs can execute at the same time. Extra runs stay queued until a slot opens.DATABASE_URLControls how the API and worker connect to PostgreSQL for run history, logs, artifacts, approvals, and result metadata.RUN_STATE_DIRControls the directory used for worker heartbeat files and optional legacy file-run imports.OUTPUT_DIRControls where generated artifacts and worker heartbeat files are written.TOOLBOX_SCRIPT_MOUNT_ROOTControls where the worker resolves toolbox PowerShell scripts.REDIS_URLControls how the API and worker connect to Redis for BullMQ.ARTIFACT_TOKEN_SECRETSigns short-lived artifact, HTML preview, and ZIP bundle URLs.
By default, Docker mounts:
./scriptsto/toolbox-scripts./outputto/app/output
Local and container startup both run Prisma migrations before the API or worker starts. You can also run them manually:
npm run db:migrateTo import legacy JSON run files from older builds into PostgreSQL:
npm run migrate:file-runsThe importer skips duplicate run ids, preserves artifacts on disk, and does not delete the old JSON files automatically.
The IMAP migration workflows orchestrate Exchange Online migration cmdlets. They do not connect to source IMAP mailboxes from Node, React, or local script code, and they do not implement a custom mailbox copy engine. Microsoft 365 migration services perform the mailbox sync after Exchange Online PowerShell creates the endpoint and batch.
Available workflows:
M365 IMAP Migration PreflightValidates the CSV path and schema, connects to Exchange Online, tests IMAP endpoint availability, and writes a readiness report.M365 IMAP Migration BatchCreates or reuses the IMAP migration endpoint, creates the migration batch from CSVData, optionally starts it, and exports batch/per-user artifacts.M365 IMAP Migration StatusReads an existing migration batch and exports the current summary and per-user statistics.
Prerequisites:
- The signed-in admin needs sufficient Exchange Online permissions to manage migration endpoints and batches.
- Target Microsoft 365 mailboxes must already exist and be licensed before migration.
- The source IMAP server must be reachable by Microsoft 365 migration services on the selected host, port, and security mode.
- IMAP migration moves mail only. It does not migrate contacts, calendars, tasks, mailbox rules, permissions, or client profiles.
- Mailbox size, item, and message size behavior still follows Exchange Online migration service limits.
CSV security and format:
Mailbox passwords must not be entered into the browser. Store the migration CSV in a local folder that is mounted into the backend container, then provide the container path in the toolbox form or set M365_TOOLBOX_IMAP_MIGRATION_CSV_PATH. The scripts validate the CSV and redact sensitive values from logs, reports, diagnostics, and artifact names.
Expected CSV headers:
EmailAddress,UserName,Password,UserRoot
target.user@contoso.com,<source-user>,<source-password>,Required headers are EmailAddress, UserName, and Password. UserRoot is optional for IMAP servers that require a virtual shared folder root.
Example compose mount:
services:
backend:
volumes:
- ./scripts:/toolbox-scripts:ro
- ./output:/app/output
- ./migration-input:/migration-input:ro
environment:
M365_TOOLBOX_IMAP_MIGRATION_CSV_PATH: /migration-input/imap-mailboxes.csvRecommended operating sequence:
- Run
M365 IMAP Migration Preflightwith the endpoint name, IMAP server, port, security mode, and CSV path or environment-backed path. - If preflight is ready, run
M365 IMAP Migration Batchwith the same endpoint settings and a unique batch name. Select auto-start only when you are ready for Microsoft 365 to begin syncing. - Run
M365 IMAP Migration Statuswith the batch name to review batch summary and per-user migration progress.
- The frontend loads the script catalog from the backend API.
- You select a script from the sidebar and fill in its approved input fields.
- The backend transforms those values into a controlled
pwshinvocation. - The script runs and the UI polls for status updates.
- If the backend concurrency limit is busy, the run stays queued until a slot opens.
- If a remediation workflow is selected, the UI requires explicit approval confirmation before launch.
- If a Microsoft device-code prompt appears in stdout or stderr, the UI opens a sign-in modal with the code, a copy button, and a direct login link.
- If the script generates artifacts, the backend serves them back for browsing, preview, and download.
- If an HTML report is generated, the UI collapses the other run cards and scrolls the report preview into view.
Docker Compose is the easiest way to deploy the project because it builds both services, wires the frontend to the backend, and mounts the folders used for scripts and generated output.
What Compose starts:
postgresInternal PostgreSQL service for persistent run history, logs, artifacts, approvals, and result metadatabackendNode/Express API, run persistence, queue endpoints, and artifact servingworkerDedicated PowerShell execution container that consumes BullMQ jobsredisInternal Redis service for BullMQ queues, retries, and dead-letter handlingfrontendNginx container serving the built React app
Named containers in the default and production compose files:
m365-toolbox-postgresm365-toolbox-redism365-toolbox-backendm365-toolbox-workerm365-toolbox-frontend
What Compose mounts:
./scriptsinto the backend container at/toolbox-scriptsas read-only./scriptsinto the worker container at/toolbox-scriptsas read-only./outputinto the backend container at/app/outputfor generated artifacts./outputinto the worker container at/app/outputfor generated artifacts
What Compose exposes:
http://localhost:5173for the frontendhttp://localhost:3001for the backend API
Available compose files:
docker-compose.ymlLocal default compose file that publishes the frontend on port5173docker-compose.prod.ymlProduction-oriented self-hosted deployment that publishes the frontend on port8080by defaultdocker-compose.coolify.ymlPlatform-friendly variant that uses a named Docker volume for report output and keeps the backend internal
Default deployment steps:
cd C:\VSCode\M365-Toolbox
docker compose build
docker compose up -dAfter deployment:
- Frontend:
http://localhost:5173 - Backend health:
http://localhost:3001/api/health
Useful Docker Compose commands:
docker compose ps
docker compose logs -f
docker compose logs -f backend
docker compose logs -f worker
docker compose logs -f redis
docker compose logs -f frontend
docker compose downDeploy with the production compose file:
cd C:\VSCode\M365-Toolbox
docker compose -f docker-compose.prod.yml up -d --buildDefault production ports:
- Frontend:
http://localhost:8080 - Backend health: internal only at
http://backend:3001/api/healthfrom the Docker network
The production compose file supports these environment overrides:
FRONTEND_ORIGINPublic frontend URL used by backend CORS validation, for examplehttps://m365toolbox.domain.comFRONTEND_PORTHost port mapped to the frontend container, default8080DATABASE_URLOptional PostgreSQL connection string override if you are not using the bundledpostgresservice defaultsARTIFACT_TOKEN_SECRETRequired HMAC secret used for signed artifact and report preview links
Example:
$env:FRONTEND_ORIGIN="https://toolbox.example.com"
$env:FRONTEND_PORT="80"
$env:ARTIFACT_TOKEN_SECRET="replace-with-a-long-random-secret"
docker compose -f docker-compose.prod.yml up -d --buildDeploy with the Coolify or Portainer-friendly compose file:
docker compose -f docker-compose.coolify.yml up -d --buildWhy this variant is different:
- the backend uses
exposeinstead of a public host port - the worker and Redis stay internal to the Compose network
- report output is stored in a named Docker volume called
toolbox_output - runtime values are expected to be supplied by the platform UI
Recommended variables for Coolify or Portainer:
FRONTEND_ORIGINSet this to the public URL of the deployed frontend, for examplehttps://toolbox.example.com. The backend normalizes the value to its origin, so an optional trailing slash or pasted path is tolerated.FRONTEND_PORTOptional host port override if you are not using a platform-managed proxyDATABASE_URLOptional PostgreSQL connection string override if your platform manages the database separatelyARTIFACT_TOKEN_SECRETRequired HMAC secret used for signed artifact, HTML preview, and ZIP bundle links
When to rebuild:
- Rebuild
backendandworkerif you change backend code or PowerShell module installation - Rebuild
frontendif you change the React UI and want the containerized build updated - Rebuild everything if you change shared package metadata or Dockerfiles
- You do not need an image rebuild for normal edits inside
scripts/orscripts/catalog/when those folders are mounted from the host
Examples:
docker compose build backend
docker compose up -d backend worker redisdocker compose build frontend
docker compose up -d frontendNotes for deployment:
- The backend persists run history in PostgreSQL, so completed runs remain visible after backend and worker restarts.
- Generated artifacts remain in the host
output/folder because it is mounted into the container. - Scripts are loaded from the host
scripts/folder, so keep that directory in place on the machine running Docker Compose. - The Coolify or Portainer-friendly compose file stores artifacts in a Docker-managed volume instead of the host
output/folder.
Install workspace dependencies:
cd C:\VSCode\M365-Toolbox
npm installThe repo includes a committed package-lock.json, so CI uses npm ci for repeatable installs.
Start both apps together:
npm run devThat starts:
- API backend on
http://localhost:3001 - PowerShell worker in watch mode
- frontend dev server on
http://localhost:5173
Before local development, make sure Redis is available on redis://127.0.0.1:6379 or set REDIS_URL to your local Redis endpoint. The frontend Vite config proxies /api requests to the backend during local development.
- Run history is persisted in PostgreSQL so completed runs survive backend and worker restarts.
- Running or queued jobs are marked as interrupted if the backend restarts before they finish.
- Toolbox-native scripts are served only from
scripts/; there is no external PowerShell repository mount. - Shared helpers such as
Shared-ToolboxReport.ps1support common HTML dashboard rendering and output handling. - The backend API exposes script listing, run creation, run status, cancellation, artifact listing, artifact download, HTML preview, queue status, and backend status endpoints.
- Input values are validated on the backend before PowerShell execution starts.
- Run retention is controlled by backend retention settings so old run records do not accumulate forever.
- CORS is restricted to configured origins, localhost, and private IPv4 ranges.
The current implementation focuses on safe execution, persistent run visibility, and better operator feedback. The next natural product steps are:
- authentication and RBAC for multi-user environments
- richer approval workflows with requester and approver identities
- stronger artifact management and retention controls
- localization when multilingual support becomes a priority
- alternative auth flows such as certificate-based or app-based execution where appropriate