Skip to content
Sponsor
3.0 preview2.3.0 stable

These docs describe the preview. Pick the version you run and every page marks what it doesn't have yet. Get the preview →
Maester 2.x docs (archived) →

Running Invoke-Maester

Invoke-Maester runs the tests and writes the report. This page covers the options you use most: which tests run, where the results go, and how the command behaves on your own terminal compared with a pipeline. The command reference lists every parameter.

Connect-Maester
Invoke-Maester

With no parameters, Invoke-Maester:

  • runs the tests that ship with Maester and the custom tests in the Custom folder of the current folder,
  • leaves out preview tests, long-running tests, Active Directory tests and installed packs,
  • runs only the tests of the services you are connected to,
  • writes the html, markdown and json reports to ./test-results and opens the html report in your browser.

Every test Maester knows about is in the result, whether it ran or not. A test that did not run carries the reason; see Applicability and reason codes.

# One test
Invoke-Maester -TestId MT.1005
# Several, with wildcards
Invoke-Maester -TestId 'MT.1005', 'CISA.MS.AAD.3.*'
# Everything except these
Invoke-Maester -ExcludeTestId 'MT.1024.*'

IDs are not case-sensitive and * is a wildcard. A test named by its exact ID in -TestId runs even if it is a preview or long-running test. -ExcludeTestId wins over -TestId.

By product, suite, area, feature or severity

Section titled “By product, suite, area, feature or severity”

Each built-in test declares what it is about. These parameters select on those attributes:

ParameterSelectsExample values
-ProductThe product whose settings the test readsentra, exchange, teams, sharepoint, defender, intune, purview, azure, github, ad
-ExcludeProductLeaves out a productthe same values as -Product
-SuiteThe set of tests it belongs tomaester, cis, cisa, asd, disa, eidsca, orca, ad
-AreaThe security areaauthentication, privileged-access
-FeatureA feature of a productconditional-access
-SeverityHow urgent a failure isCritical, High, Medium, Low, Info
# The Entra tests
Invoke-Maester -Product entra
# Entra and Exchange Online, Critical and High only
Invoke-Maester -Product entra, exchange -Severity Critical, High
# Everything except Exchange Online and Teams
Invoke-Maester -ExcludeProduct exchange, teams
# The CISA tests about authentication
Invoke-Maester -Suite cisa -Area authentication
# The Conditional Access tests
Invoke-Maester -Feature conditional-access

The rules for combining them:

  • The values of one parameter are alternatives: -Product entra, exchange is Entra or Exchange Online.
  • Different parameters must all match: -Product entra -Severity High is Entra and High.
  • -Product also matches a test’s related products, and accepts aliases such as 'Entra ID' or exo.
  • -Product, -ExcludeProduct, -Suite, -Area and -Feature accept * wildcards.
  • -ExcludeProduct and -ExcludeTestId win over every selector.
  • A Pester-format custom test has no product, so -ExcludeProduct never leaves it out.

The test catalog shows the product, area, feature and severity of every test.

Invoke-Maester -IncludePreview -IncludeLongRunning

Preview tests are new. They are left out of a default run so you can try them first and tell us what you find before they become part of every run; include them to test them and give feedback. Long-running tests can take a long time in a tenant with many objects. Both are left out unless you ask for them or name the test by its exact ID.

# Built-in tests plus the custom tests and maester-config.json in ./maester
Invoke-Maester ./maester
# Only your custom tests
Invoke-Maester -Path ./maester/Custom -SkipBuiltIn

See Writing custom tests.

A pack is a set of tests that someone else publishes and you add to your runs. A pack never runs just because it is there: it runs only when you name it with -Pack, use -AllPacks, or turn it on in the configuration.

# Built-in tests plus one pack
Invoke-Maester -Pack ZTA
# Only that pack
Invoke-Maester -Pack ZTA -SkipBuiltIn
# Built-in tests plus every installed pack
Invoke-Maester -AllPacks
# No packs at all, whatever the configuration turns on
Invoke-Maester -SkipPack

-Pack takes a pack’s code or its ID, and accepts * wildcards. A pack you name runs with its preview and long-running tests included. See Maester Packs to find and install packs.

Active Directory tests run only after you connect to it, and need no Microsoft Graph connection:

Connect-Maester -Service ActiveDirectory
Invoke-Maester -Product ad

-DryRun works out which tests would run, and why the others would not, without running any of them:

$plan = Invoke-Maester -Product entra -DryRun -PassThru
$plan.Tests | Group-Object ReasonCode

A test that would have run has the reason code DryRun. The report files are still written, so you can open the report and look at the plan. Pester-format custom tests still go through Pester discovery, which runs their BeforeDiscovery and Describe-level code.

Anything you select on the command line can live in maester-config.json instead, so a scheduled run and a run on your own machine choose the same tests. See the run configuration reference.

ParameterWhat it does
-OutputFolderWrites every format (html, markdown, markdown summary, json) to this folder, with a timestamp in the file names. Defaults to ./test-results when no -Output* parameter is set.
-OutputFolderFileNameThe file name to use in the output folder, instead of the timestamped one.
-OutputHtmlFile, -OutputMarkdownFile, -OutputMarkdownSummaryFile, -OutputJsonFileWrites only the formats you name, each to the file given. Ignored when -OutputFolder is set.
-ExportCsv, -ExportExcelAdds a CSV or Excel file to the output folder.
-PassThruReturns the results as an object, for a script that goes on to read them.
-MailRecipient, -TeamId and -TeamChannelId, -TeamChannelWebhookUriSends the results by mail or posts a summary to a Teams channel. See Alerts.

See Exporting results for the formats and the result schema for the object and the json file.

In a scheduled task, a pipeline or any script nobody watches, add -NonInteractive:

$results = Invoke-Maester -NonInteractive -PassThru -OutputFolder ./test-results
if ($results.FailedCount -gt 0) { exit 1 }

-NonInteractive leaves out the logo, the dashboard, the connection details, the run summary and the check for a newer version, and does not open the report in a browser. Warnings and errors are still written.

Without it, Maester opens the html report whenever PowerShell says the session is interactive. A build agent can report that too; opening the report then fails and Maester writes a warning. -NonInteractive avoids that. Starting PowerShell itself with pwsh -NonInteractive has the same effect on the browser.

See Automate for ready-made pipelines.

Invoke-Maester writes to the console in one of three modes. With -OutputMode Auto, the default, it looks at where it is running and picks one.

ModeWhat you seePicked when
InteractiveA full-screen dashboard: the phases of the run, a progress bar, the tests that are running, result counts and panels about the tenant. When the run ends your screen is restored and the summary is written.You run it yourself in a terminal.
StreamLines only, with a progress line every 50 tests or 10 seconds. Nothing is redrawn, so it reads well in a log.A pipeline, redirected output, -NonInteractive, or a host that cannot draw the dashboard.
PlainStream without colour or Unicode symbols.TERM is dumb.

The mode is decided in this order. The first one that applies wins.

  1. -OutputMode Interactive, Stream or Plain.

  2. The MAESTER_OUTPUT_MODE environment variable, with the same values.

  3. Output.ConsoleMode in maester-config.json.

  4. Detection:

    What Maester findsMode
    TERM=dumbPlain
    GitHub Actions (GITHUB_ACTIONS=true), Azure Pipelines (TF_BUILD=True) or another CI system (CI set to anything but false)Stream
    Output is redirected to a file or a pipeStream
    -NonInteractiveStream
    The PowerShell host is not the console host, or the terminal does not support virtual terminal sequencesStream
    None of the aboveInteractive

Asking for Interactive where the dashboard cannot be drawn (redirected output, a host that is not the console host) gives you Stream.

  • It needs a console of at least 80 columns and 16 rows. In a smaller one, Maester keeps a two-line status at the bottom of the console instead.
  • The panels on the right appear when the console is about 140 columns or wider. Output.DashboardPanels in the run configuration chooses the panels and their order.
  • -Verbosity Normal writes one line for each finished test, and Detailed also a line when each test starts. The lines need the scrollback, so the two-line status is used instead of the full-screen dashboard.
  • Warnings and errors written while the dashboard is on screen are held back and written once the run ends, so none are lost.
  • In Windows Terminal and the VS Code terminal, Maester switches the console to UTF-8 for the run so the dashboard can be drawn, and puts the earlier encoding back afterwards.

To turn the dashboard off on your own terminal:

Invoke-Maester -OutputMode Stream

or set it once for every run:

$env:MAESTER_OUTPUT_MODE = 'Stream'

On GitHub Actions and Azure Pipelines, Stream also:

  • folds parts of the output into collapsible log groups,
  • writes the first 20 Failed rows as warning annotations and Error rows as error annotations. Set Output.CIAnnotations to false in the run configuration to leave them out.
  • Setting the NO_COLOR environment variable turns colour off in every mode. So does TERM=dumb and $PSStyle.OutputRendering = 'PlainText'.
  • Output redirected to a file or a pipe gets no colour codes, unless you asked for a mode or the CI system is known to render them.
  • -NoLogo leaves out only the logo.