Configuration overview
Maester uses a configuration file called maester-config.json to customize how tests are run and to define global settings for your environment. This guide explains the basics; the run configuration reference lists every section and key.
How Configuration Works
Section titled “How Configuration Works”From Maester 3.0 the tests carry their own defaults (severity, parameters), and the module no longer ships a configuration file with a row per test. Your configuration only holds what you want to change.
Maester reads these files from the folder you pass with -Path (or the current folder), each one optional:
maester-config.json- your main configuration. Maester looks in-Path,-Path/testsand up to five parent folders.custom/maester-config.json- an overlay on the main file, for example settings owned by a different team.maester-config.<tenantId>.json- settings for one tenant, merged over the other two once Maester knows which tenant you are connected to.
Each file merges over the one before, so a tenant file only needs the values that differ for that tenant.
Instead of files next to your tests, you can pass a configuration with Invoke-Maester -Config (a path, an object, or several merged left to right) or the MAESTER_CONFIG environment variable. Then the files next to your tests are not read.
Configuration File Structure
Section titled “Configuration File Structure”The configuration file has two main sections:
{ "GlobalSettings": { // Organization-wide settings that apply to multiple tests }, "TestSettings": [ // Test-specific settings like severity levels ]}GlobalSettings
Section titled “GlobalSettings”The GlobalSettings section contains organization-wide configuration that can be used by multiple tests. For example, you can define your emergency access accounts here so that all related tests use the same accounts.
A test receives a global setting as one of its parameters, so Get-MtTest shows which tests use it and the result shows the value each test ran with. To give one test a different value, set the parameter in that test’s TestSettings row; it wins over GlobalSettings:
{ "GlobalSettings": { "ParkedDomains": ["contoso-old.com"] }, "TestSettings": [ { "Id": "CIS.M365.2.1.9", "Parameters": { "ParkedDomains": [] } } ]}Maester checks GlobalSettings once, before any test runs:
- A value of the wrong type, or one the setting does not allow, stops the run with a message that names the setting.
- A key Maester does not know gives a warning that names the closest setting, so a typo such as
ParkedDomainis not silently ignored. - A setting marked sensitive is written to the results as
[redacted].
Your own custom tests can have settings too. Name them Namespace.Key, for example Contoso.Regions, so they cannot collide with a setting of Maester or of a pack. A Maester Pack declares the settings it reads, and they are checked the same way when the pack runs. The run configuration reference lists every setting Maester knows.
XSPM external data sources
Section titled “XSPM external data sources”The XSPM unified identity query uses Advanced Hunting externaldata sources to enrich identity results. You can override these sources with HTTPS mirrors by adding XspmExternalDataUris to the GlobalSettings section of your custom configuration:
{ "GlobalSettings": { "XspmExternalDataUris": { "EntraDirectoryRoles": "https://mirror.contoso.com/Classification_EntraIdDirectoryRoles.json", "MicrosoftApps": "https://mirror.contoso.com/MicrosoftApps.json", "ApiPermissions": "https://mirror.contoso.com/Classification_ApiPermissions.json", "ArmApiRequests": "https://mirror.contoso.com/ArmApiRequest.csv" } }}All values must be absolute HTTPS URIs. Because externaldata is evaluated by Defender Advanced Hunting, the mirror must be reachable by that service, not only by the computer running Maester. See Microsoft’s Advanced Hunting best practices for details.
Omitted keys retain their built-in defaults. A mirror must preserve the original JSON or CSV schema. Use an immutable commit URL or a versioned mirror object when reproducible classification is required; the default URLs still track upstream branches. User information and fragments in URIs are rejected. Signed query strings are supported, but treat the configuration file as a secret and grant only read access to the mirrored data. Maester suppresses verbose configuration/query logging on this path and redacts configured query strings in its diagnostic message. This does not control logging by the service or by external instrumentation.
TestSettings
Section titled “TestSettings”The TestSettings section changes individual tests by ID: severity, turning a test off, parameter values and timeouts.
{ "TestSettings": [ { "Id": "MT.1005", "Severity": "Critical" }, { "Id": "MT.1089", "Enabled": false, "Reason": "Not relevant for this tenant" }, { "Id": "MT.1198", "Parameters": { "MaximumValidityDays": 180 } } ]}A disabled test is not run and appears in the report as Not run with the reason you gave. See Severity Levels and the run configuration reference.
Other sections
Section titled “Other sections”Selection (which tests run), Environment (facts about the tenant and which applicability checks are enforced), Execution (timeouts), Output (CI test result files) and Metadata (labels echoed in the results) are described in the run configuration reference.
Creating Your Configuration
Section titled “Creating Your Configuration”Maester runs with its default settings when there is no config file, so you only need one to change something. Create maester-config.json in a folder and run Invoke-Maester -Path <folder> (or run Maester from that folder), or pass the file with Invoke-Maester -Config <file> or the MAESTER_CONFIG environment variable. Only include the settings you want to change. Here’s a complete example:
{ "GlobalSettings": { "EmergencyAccessAccounts": [ { "Type": "User" }, { "Id": "00000000-0000-0000-0000-000000000000", "Type": "Group" } ] }, "TestSettings": [ { "Id": "MT.1005", "Severity": "Critical" } ]}Available Global Settings
Section titled “Available Global Settings”The following global settings are available for customization:
| Setting | Description | Documentation |
|---|---|---|
EmergencyAccessAccounts | Define your break glass accounts and groups | Emergency Access Accounts |
ParkedDomains | Accepted domains that never send email; the email authentication checks expect them to deny all mail | This page |
DefenderEndpointPolicyFiltering | Which Defender for Endpoint policies the Defender checks read: All, IncludeUnassigned or OnlyAssigned (default) | This page |
DefenderEndpointComplianceLogic | How the Defender for Endpoint checks combine policies: EffectivePolicy (default), AllPolicies or AnyPolicy | This page |
XspmExternalDataUris | Override the HTTPS sources used by XSPM Advanced Hunting queries | This page |
The GitHub and Dataverse settings are listed in the run configuration reference.
How Settings Are Merged
Section titled “How Settings Are Merged”When several files are found, each one merges over the one before:
TestSettingsrows are matched byId, and each property you set replaces the same property in the lower file.- Other sections are merged key by key.
- Lists replace lists: an empty list in a higher file clears the lower one.
This means you only need to include the settings you want to change or add.
Validating Your Configuration
Section titled “Validating Your Configuration”Run Maester without running any test to see which configuration it used and what it would do:
$plan = Invoke-Maester -DryRun -PassThru$plan.MaesterConfig.ConfigSource # the files that were read$plan.Tests | Group-Object Result, ReasonCodeSee Applicability and reason codes for what each reason means.