Sending reports

On the roadmap — not in the private preview MVP yet. Uploading reports yourself through the API (the uploader script below) isn't available yet for self-hosted. Today, Maester Cloud runs your tests for you through the built-in Maester Cloud Runner, using the Microsoft Graph connection from setup, and results land in the portal automatically. This page describes the upload flow that's coming.

Maester Cloud accepts two report families: Maester test results (the JSON produced by Invoke-Maester) and the Zero Trust Assessment report. You send them with the uploader script from wherever your runs happen.

The command

./Send-MaesterCloudReport.ps1 `
  -JsonPath ./TestResults.json `
  -HtmlPath ./TestResults.html `
  -ApiBaseUrl https://your-name.maester.cloud `
  -AccessToken $token `
  -Source "GitHub Actions"
  • -JsonPath is required; -HtmlPath is optional but recommended, because the original HTML report is stored and viewable from the portal.
  • -AccessToken is an Entra access token from your tenant. Your environment only accepts tokens from the tenant it was onboarded for.
  • -Source is a free-text label ("GitHub Actions", "Azure Automation") shown on every run for provenance.

What happens after you send

  1. Upload-init: the script asks your environment for short-lived, write-only upload URLs after validating your token (issuer, audience, and tenant must match your deployment).
  2. Artifacts upload: the JSON (and HTML) are written to your environment's private storage. The manifest is written last, deliberately: processing never starts on a half-uploaded report.
  3. Processing: a durable workflow identifies the report family, confirms the assessed tenant, and parses every test into a stored result: id, title, outcome, severity, block, tags, and the Microsoft product it belongs to. Transient failures retry automatically.
  4. Recording: the run appears in the portal with pass/fail/skip counts; the raw files stay downloadable as evidence; and the run is diffed against your previous one.

Run it on a schedule

Drift is only as fresh as your runs. Most customers schedule a daily run (a GitHub Actions workflow, an Azure DevOps pipeline, or Azure Automation) ending with the uploader command. Real PowerShell-written files (including UTF-8 BOMs) are handled as-is; no massaging needed.

Statuses you'll see

StatusMeaning
SucceededParsed and recorded; results, products, and drift are available.
Processing / UploadedIn flight, usually seconds.
RetryingA transient failure; the workflow retries automatically.
FailedThe report couldn't be understood (e.g. no tenant ID). The raw files are kept so nothing is lost; the error is shown on the run.