30-second answer

PowerShell
m365-governance run

It plans, collects what the target can reach, evaluates the evidence and writes the report.

Why it exists

A tenant assessed end to end was ten collect commands and then an evaluate, and the person running them had to know what a slice is before obtaining a first result. Choosing among ten is a decision this engine can make from the target it was given, and asking somebody to make it before they have seen a single finding is asking them to learn the architecture in order to use the tool.

It says what it will not do, before it does anything

Text
Plan: 10 of 11 collections

  run      sites            every site this identity can enumerate
  run      owners           who administers one site
  …

  not run  conditional-access  reads Microsoft Graph, and this engine never
                              acquires a token: set one to include it

  A collection that was not attempted is not a resource that is not
  there. Nothing below reads these, and no rule over the evidence
  can recover what they would have said.

Every collection appears with a verdict, including the ones that will not happen. A run that quietly skipped half its slices would produce a report that looks complete to the only person who could tell that it is not. It is the same reason unknown is never a pass.

The plan also refuses what this machine cannot do. Without PowerShell 7 it plans nothing and says so, rather than promising ten collections it would refuse a moment later.

--dry-run prints the plan and reaches no tenant.

A collection that fails does not end the run

Six of fifty-three sites refusing a collector is a fact about coverage, not a reason to produce nothing. Each collection carries its own manifest saying whether it was completed, partial, failed or cancelled, and the report is built over what was actually gathered.

Options

--project names the project file. Omit it to use the nearest m365-governance.toml from here upwards, which is what setup writes. Everything below that the file already holds can be left out.

--client-id, --tenant-url and --site-url are the identity and the target, as in setup.

--device-login signs in with a device code, for hosts with no browser. --tenant-id, --certificate-path and --certificate-password-env sign in as an application with a certificate instead of a person; the password is the name of an environment variable, never the password.

--output is where the evidence is written. It is kept, because it is what the conclusions were decided from, and a report without it cannot be checked.

--profile is a profile file; the packaged default selects every rule. --rules is a directory of rule files, and it replaces the shipped rules entirely rather than adding to them.

--format is markdown, json or html, and --out writes the report there. --bundle writes one folder per run, holding the run document, the evidence it was decided from and its report; nothing new is computed.

--fail-on is nothing, fail or unresolved, and exits 1 on findings. unresolved counts unknown and invalid-evidence alongside fail.

--dry-run prints the plan and reaches no tenant.

What it does not do

It decides nothing a rule decides, it merges no evidence, and it does not make a slice apply to a target it does not apply to. Every step in it is a command that exists on its own: collect for the parts, evaluate for the reading, assess for a document somebody else can check.