Skip to content
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) →

Sponsor

Connect-Maester - Advanced

There are two main methods of authenticating sessions for use with Maester:

  • Within the Maester module
  • Within the respective modules for the tests

The Maester module integrates with the following modules:

  • Microsoft.Graph.Authentication
  • Az.Accounts
  • ExchangeOnlineManagement
  • MicrosoftTeams

The Maester module includes Connect-Maester to provide coverage for common scenarios. The parameter set options afford a user of the module the ability to test with common interactive methods. The Microsoft Graph API is the default authentication service, and more specifically the Microsoft Graph PowerShell SDK. Coverage for tests shipping with Maester have at least one option available in general.

The objective of the Maester module is not to replace or consolidate the authentication options across the many possible testing sources.

Within the respective modules for the tests

Section titled “Within the respective modules for the tests”

Recommended for automation use

The Maester module provides a framework for creating, executing, and reporting on configuration state using tests. Each test can rely on one or more sources to perform validation. Each source a test validates may be available without authentication (e.g., Domain Name System) or may require authentication to a specific environment (e.g., Microsoft Graph API).

The recommendation for authenticating to modules necessary to support tests for the most extensibility is to authenticate within those source modules and running Invoke-Maester with the -SkipGraphConnect property.

As an example, connecting to the Microsoft Graph PowerShell SDK module as a managed identity and then running Maester.

Running Connect-Maester is not required to use Invoke-Maester.

Connect-MgGraph -Identity -NoWelcome
Invoke-Maester -SkipGraphConnect -NonInteractive

The following diagram provides a general overview of command dependency relationships. You can extend Maester with your own tests that leverage other modules as may be beneficial. There is no dependency for your own tests to rely on the Connect-Maester capabilities.

graph TD;
  Connect-Maester-->Microsoft.Graph.Authentication;
  Connect-Maester-->Az.Accounts;
  Connect-Maester-->ExchangeOnlineManagement;
  Connect-Maester-->a[Additional Modules];
  Microsoft.Graph.Authentication-->Get-MgContext;
  Microsoft.Graph.Authentication-->Get-MgEnvironment;
  Microsoft.Graph.Authentication-->Invoke-MgGraphRequest;
  Az.Accounts-->Get-AzContext;
  Az.Accounts-->Invoke-AzRestMethod;
  ExchangeOnlineManagement-->Get-ConnectionInformation;
  ExchangeOnlineManagement-->Get-EXOMailbox;
  ExchangeOnlineManagement-->Get-MtExo;
  Get-MtExo-->Get-AcceptedDomain;
  Get-MtExo-->o[Other Commands];

You can write tests that expand Maester to validate the configuration state of infrastructure in the cloud, on-premises, and entirely unrelated to Microsoft products.

For use with the Maester tests the following provides an overview of creating the necessary service principal.

  • Open Entra admin center > Identity > Applications > App registrations
  • Select New registration
  • Enter a name for the application (e.g. Maester DevOps Account)
  • Select Register
  • Open the application you created in the previous step
  • Select API permissions > Add a permission
  • Select Microsoft Graph > Application permissions
  • Search for each of the permissions and check the box next to each permission:
    • AuditLog.Read.All
    • DeviceManagementConfiguration.Read.All
    • DeviceManagementManagedDevices.Read.All
    • DeviceManagementRBAC.Read.All
    • DeviceManagementServiceConfig.Read.All
    • Directory.Read.All
    • DirectoryRecommendations.Read.All
    • EntitlementManagement.Read.All
    • IdentityRiskEvent.Read.All
    • NetworkAccess.Read.All
    • OnPremDirectorySynchronization.Read.All
    • OrgSettings-AppsAndServices.Read.All
    • OrgSettings-Forms.Read.All
    • Policy.Read.All
    • Policy.Read.ConditionalAccess
    • Reports.Read.All
    • ReportSettings.Read.All
    • RoleEligibilitySchedule.Read.Directory
    • RoleManagement.Read.All
    • RoleManagementAlert.Read.Directory
    • SecurityIdentitiesSensors.Read.All
    • SecurityIdentitiesHealth.Read.All
    • SharePointTenantSettings.Read.All
    • ThreatHunting.Read.All
    • UserAuthenticationMethod.Read.All

    To run preview Agent ID tests, also grant these application permissions:

    • AgentIdentity.Read.All
    • AgentIdentityBlueprint.Read.All
    • AgentIdentityBlueprintPrincipal.Read.All
    • Application.Read.All
  • Optionally, search for each of the permissions if you want to allow privileged permissions:
    • ReportSettings.ReadWrite.All
      • Required to disable report obfuscation
  • Select Add permissions
  • Select Grant admin consent for [your organization]
  • Select Yes to confirm
(Optional) Grant permissions to Exchange Online

(Optional) Grant permissions to Exchange Online

Section titled “(Optional) Grant permissions to Exchange Online”

The Exchange Online role-based access control (RBAC) implementation uses service-specific roles for applications. The configuration below establishes the authorization chain for the app registration you created in the previous steps.

The Exchange Online permissions are necessary to support tests that validate Exchange Online configurations, such as the CISA tests.

  • Open the application you created in the previous step
  • Select API permissions > Add a permission
  • Select APIs that my organization uses > search for Office 365 Exchange Online > Application permissions
  • Search for Exchange.ManageAsApp
  • Select Add permissions
  • Select Grant admin consent for [your organization]
  • Select Yes to confirm
  • Connect to the Exchange Online Management tools and use the following to set the appropriate permissions:
New-ServicePrincipal -AppId <Application ID> -ObjectId <Object ID> -DisplayName <Name>
New-ManagementRoleAssignment -Role "View-Only Configuration" -App <DisplayName from previous command>
(Optional) Grant permissions to Teams

The Teams role-based access control (RBAC) implementation uses service-specific roles for applications. The configuration below establishes the authorization chain for the app registration you created in the previous steps.

The Teams permissions are necessary to support tests that validate Teams configurations.

  • Open Roles and administrators
  • Search and select Teams Reader
  • Select Add assigment
  • Select No member selected
  • Search for the name of previously created application
  • Select previously created application and select Select to confirm
  • Select Next to confirm
  • Ensure that Active and Permanently assigned are ticked
  • Enter Justification
  • Select Assign to confirm
(Optional) Grant permissions to Azure

The Azure Role-Based Access Control (RBAC) implementation uses Uniform Resource Names (URNs) with a ”/” separator for hierarchical scoping. Some resources exist within the root (e.g., ”/”) scope, and Microsoft retains strict control over them by limiting supported interactions. As a Global Administrator, you can elevate access to become authorized for these limited interactions.

The Azure RBAC permissions are necessary to support tests that validate Azure configurations, such as the CISA tests.

The following PowerShell script will enable you, with a Global Administrator role assignment, to:

  • Identify the Service Principal Object ID that will be authorized as a Reader (Enterprise app Object ID)
  • Install the necessary Az module and prompt for connection
  • Elevate your account access to the root scope
  • Create a role assignment for Reader access over the Root Scope
  • Create a role assignment for Reader access over the Entra ID (i.e., aadiam provider)
  • Identify the role assignment authorizing your account access to the root scope
  • Delete the root scope role assignment for your account
$servicePrincipal = "<Object ID of the Entra App>"
$subscription = "<Subscription ID>"
Install-Module Az.Accounts -Force
Install-Module Az.Resources -Force
Connect-AzAccount
#Elevate to root scope access
$elevateAccess = Invoke-AzRestMethod -Path "/providers/Microsoft.Authorization/elevateAccess?api-version=2015-07-01" -Method POST
#Assign permissions to Enterprise App
New-AzRoleAssignment -ObjectId $servicePrincipal -Scope "/" -RoleDefinitionName "Reader" -ObjectType "ServicePrincipal"
New-AzRoleAssignment -ObjectId $servicePrincipal -Scope "/providers/Microsoft.aadiam" -RoleDefinitionName "Reader" -ObjectType "ServicePrincipal"
#Remove root scope access
$assignment = Get-AzRoleAssignment -RoleDefinitionId 18d7d88d-d35e-4fb5-a5c3-7773c20a72d9|?{$_.Scope -eq "/" -and $_.SignInName -eq (Get-AzContext).Account.Id}
$deleteAssignment = Invoke-AzRestMethod -Path "$($assignment.RoleAssignmentId)?api-version=2018-07-01" -Method DELETE
(Optional) Grant permissions to SharePoint Online

(Optional) Grant permissions to SharePoint Online

Section titled “(Optional) Grant permissions to SharePoint Online”

SharePoint Online tests require the PnP.PowerShell module and an Entra ID app registration configured for interactive login with SharePoint delegated permissions.

The SharePoint Online permissions are necessary to support tests that validate SharePoint Online configurations, such as the CISA SharePoint baseline controls.

Install-Module PnP.PowerShell -Scope CurrentUser

The easiest way to create the required app registration is to follow the official PnP PowerShell guide:

Option A — Automatically create a new PnP app registration

Section titled “Option A — Automatically create a new PnP app registration”

PnP provides a built-in cmdlet to create a dedicated app registration for interactive login. This is the quickest option and the one recommended in the PnP docs:

Register-PnPEntraIDAppForInteractiveLogin -ApplicationName "Maester PnP" -Tenant [yourtenant].onmicrosoft.com -SharePointDelegatePermissions "AllSites.FullControl"

This will:

  • Create an Entra ID app registration with the required delegated permissions
  • Configure http://localhost as the redirect URI automatically
  • Prompt you to authenticate and provide consent
  • Output the Client ID you will need for Connect-Maester

If you prefer to start from the exact example in the PnP docs, run Register-PnPEntraIDAppForInteractiveLogin with their default parameters and add -SharePointDelegatePermissions "AllSites.FullControl" for Maester’s SharePoint tests.

Note: Maester’s SharePoint tests are read-only. AllSites.FullControl (delegated) is sufficient.

Important: After registering the app, open a new PowerShell session before running Connect-Maester, as the registration process loads PnP assemblies that can conflict with Microsoft Graph.

Option B — Reuse the existing Maester app registration

Section titled “Option B — Reuse the existing Maester app registration”

If you prefer not to create a separate app, you can update the Maester app registration you created earlier to also support PnP PowerShell interactive login.

1. Add the localhost redirect URI

  • Open your Maester app registration in the Entra admin center
  • Select Authentication > Add a platform > Mobile and desktop applications
  • In the Custom redirect URIs field, enter http://localhost (note: http, not https)
  • Select Configure

2. Add SharePoint delegated permissions

  • Select API permissions > Add a permission
  • Select SharePoint > Delegated permissions
  • Search for and check AllSites.FullControl
  • Select Add permissions
  • Select Grant admin consent for [your organization] and confirm

3. Connect using the existing Client ID

You can retrieve the Client ID of your Maester app from Graph without looking it up manually. First connect to Graph, then query for the app by its display name:

# Connect to Graph first
Connect-Maester -Service Graph
# Retrieve the Client ID of the Maester app registration
$clientId = (Get-MgApplication -Filter "displayName eq 'Maester DevOps Account'").AppId

Then connect to SharePoint Online in a new session using the retrieved Client ID. The SharePoint admin URL is auto-discovered from your tenant — no need to specify it manually:

# Open a new PowerShell session, then:
Connect-Maester -Service Graph,SharePointOnline -SharePointClientId $clientId

Important: After registering the app, open a new PowerShell session before running Connect-Maester, as PnP assemblies loaded during the session can conflict with Microsoft Graph.

Option C — App-only access (automation / non-interactive)

Section titled “Option C — App-only access (automation / non-interactive)”

For unattended runs (CI pipelines, scheduled tasks) where interactive login is not possible, use application permissions with certificate-based authentication.

1. Add SharePoint application permission

  • Open your app registration in the Entra admin center
  • Select API permissions > Add a permission
  • Select SharePoint > Application permissions
  • Search for and check Sites.FullControl.All
  • Select Add permissions
  • Select Grant admin consent for [your organization] and confirm

2. Upload a certificate

  • Select Certificates & secrets > Certificates > Upload certificate
  • Upload the public key (.cer) of your certificate

3. Connect using Connect-Maester

Pass the certificate thumbprint directly to Connect-Maester using -SharePointCertificateThumbprint. -TenantId is required for thumbprint-based auth:

$params = @{
Service = @('Graph', 'SharePointOnline')
SharePointClientId = "<App Client ID>"
SharePointCertificateThumbprint = "<Certificate Thumbprint>"
TenantId = "<Tenant ID or domain>"
}
Connect-Maester @params

The certificate must be present in the current user’s Windows certificate store. The SharePoint admin URL is auto-discovered — supply -SharePointAdminUrl to override it if needed.

Use the Client ID from Option A or Option B when connecting:

Connect-Maester -Service Graph,SharePointOnline -SharePointClientId "<Client ID>"

The SharePoint admin URL is auto-discovered from your tenant’s initial domain. If auto-discovery does not work (e.g. government or custom-domain tenants), supply it explicitly:

Connect-Maester -Service Graph,SharePointOnline -SharePointClientId "<Client ID>" -SharePointAdminUrl "https://contoso-admin.sharepoint.com"

For device code flow (e.g. non-interactive sessions):

Connect-Maester -Service Graph,SharePointOnline -SharePointClientId "<Client ID>" -UseDeviceCode
(Optional) Grant Dataverse permissions for Copilot Studio tests

(Optional) Grant Dataverse permissions for Copilot Studio

Section titled “(Optional) Grant Dataverse permissions for Copilot Studio”

Dataverse access is required for the Copilot Studio security tests (MT.1113–MT.1122) that evaluate Copilot Studio agent configurations.

Create an Application User in Power Platform

Section titled “Create an Application User in Power Platform”
  1. Go to the Power Platform Admin Center → select your environment → Settings → Users + permissions → Application users
  2. Click New app user → Add an app → select the app registration created above
  3. Select the correct Business unit
  4. Assign a security role with read access:
    • Basic User for simplicity, or
    • A custom role (e.g. Maester Security Reader) with Organization-level Read on: Agent (bot), Agent component (botcomponent), User (systemuser), and Connection Reference (connectionreference)
  5. Click Create

Add the environment URL to maester-config.json:

{
"GlobalSettings": {
"DataverseEnvironmentUrl": "https://org12345.crm.dynamics.com"
}
}

You may have a need to use Maester with multiple tenants. The Maester tests enable you to accomplish this, but it is best to authenticate within the respective modules for the tests you wish to run.

The Microsoft Graph PowerShell SDK Module provides many options for authenticating.

Section titled “OAuth token-based authentication (recommended for automation)”

If you already have an authenticated Azure context, you can use Get-AzAccessToken to obtain an OAuth token and pass it directly to Connect-MgGraph.

$graphToken = Get-AzAccessToken -ResourceUrl 'https://graph.microsoft.com' -AsSecureString
Connect-MgGraph -AccessToken $graphToken.Token -NoWelcome

Below is an example of using a X.509 Certificate private key file, $cert, to authenticate to $tenantId as the $applicationId service principal.

#$applicationId = "xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx"
#$tenantId = "xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx"
#$b64 = Get-Content .\path\to\cert.pfx -Raw
#$b64 = Get-AzKeyVaultSecret -VaultName $keyVaultName -Name $applicationDisplayName -AsPlainText
#$bytes = [Convert]::FromBase64String($b64)
#$cert = [System.Security.Cryptography.X509Certificates.X509Certificate2]::new($bytes)
Connect-MgGraph -AppId $applicationId -Certificate $cert -TenantId $tenantId -NoWelcome

Microsoft Azure Accounts PowerShell Module

Section titled “Microsoft Azure Accounts PowerShell Module”

The Microsoft Azure Accounts PowerShell Module provides many options for authenticating. Below is an example of using a X.509 Certificate private key file to authenticate to $tenantId as the $applicationId service principal.

#$applicationId = "xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx"
#$tenantId = "xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx"
Connect-AzAccount -ServicePrincipal -ApplicationId $applicationId -TenantId $tenantId -CertificatePath /cert.pfx

Microsoft Exchange Online and Security & Compliance PowerShell Modules

Section titled “Microsoft Exchange Online and Security & Compliance PowerShell Modules”

The Microsoft Exchange Online and Security & Compliance PowerShell Modules provide many options for authenticating.

Section titled “OAuth token-based authentication (recommended for automation)”

If you already have an authenticated Azure context (e.g., managed identity, workload identity federation, or Connect-AzAccount), you can use Get-AzAccessToken to obtain OAuth tokens and pass them directly. This eliminates the need for certificate management.

#$clientId = "xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx"
#$tenantId = "xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx"
#$moera = "contoso.onmicrosoft.com"
# Exchange Online
$outlookToken = ConvertFrom-SecureString -SecureString (Get-AzAccessToken -ResourceUrl 'https://outlook.office365.com' -AsSecureString).Token -AsPlainText
Connect-ExchangeOnline -AccessToken $outlookToken -AppId $clientId -Organization $tenantId -ShowBanner:$false
# Security & Compliance (IPPS)
$isspToken = ConvertFrom-SecureString -SecureString (Get-AzAccessToken -ResourceUrl 'https://ps.compliance.protection.outlook.com' -AsSecureString).Token -AsPlainText
Connect-IPPSSession -AccessToken $isspToken -Organization $moera

Connect-ExchangeOnline accepts the tenant ID as the -Organization value, while Connect-IPPSSession requires the tenant’s Microsoft Online Email Routing Address (MOERA), e.g., contoso.onmicrosoft.com.

Below is an example of using a X.509 Certificate private key file, $cert, to authenticate to $tenantId as the $applicationId service principal.

These modules don’t reference the tenant ID GUID for authentication, they instead use the tenant’s Microsoft Online Email Routing Address (MOERA).

#$applicationId = "xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx"
#$b64 = Get-Content .\path\to\cert.pfx -Raw
#$b64 = Get-AzKeyVaultSecret -VaultName $keyVaultName -Name $applicationDisplayName -AsPlainText
#$bytes = [Convert]::FromBase64String($b64)
#$cert = [System.Security.Cryptography.X509Certificates.X509Certificate2]::new($bytes)
#$domains = Invoke-MgGraphRequest -Uri https://graph.microsoft.com/v1.0/domains
#$moera = ($domains.value|?{$_.isInitial}).id
Connect-ExchangeOnline -Certificate $cert -AppID $applicationId -Organization $moera -ShowBanner:$false
Connect-IPPSSession -Certificate $cert -AppID $applicationId -Organization $moera -ShowBanner:$false

The Microsoft Teams PowerShell Module supports both interactive and non-interactive authentication methods.

Section titled “OAuth token-based authentication (recommended for automation)”

Connect-MicrosoftTeams accepts two access tokens via the -AccessTokens parameter: a Microsoft Graph token and a Teams-specific token. This approach works well when you already have an authenticated Azure context.

$graphToken = Get-AzAccessToken -ResourceUrl 'https://graph.microsoft.com' -AsSecureString
$teamsToken = Get-AzAccessToken -ResourceUrl '48ac35b8-9aa8-4d74-927d-1f4a14a0b239' -AsSecureString
$tokens = @(
(ConvertFrom-SecureString -SecureString $graphToken.Token -AsPlainText),
(ConvertFrom-SecureString -SecureString $teamsToken.Token -AsPlainText)
)
Connect-MicrosoftTeams -AccessTokens $tokens

The resource URL 48ac35b8-9aa8-4d74-927d-1f4a14a0b239 is the application ID for the Microsoft Teams PowerShell module.

Interactive and certificate-based authentication

Section titled “Interactive and certificate-based authentication”

For interactive sessions, you can use the standard login prompt. For non-interactive use with certificates, service principal authentication is supported.

# Interactive
Connect-MicrosoftTeams
# Non-Interactive (Service Principal)
$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2("C:\exampleCert.pfx",$password)
Connect-MicrosoftTeams -Certificate $cert -ApplicationId $applicationId -TenantId $tenantId

The Copilot Studio security tests (MT.1113–MT.1122) use the Dataverse OData API via Az.Accounts. Authenticate with Connect-AzAccount and then connect Maester for Copilot Studio access.

# Authenticate to Az (SPN example)
Connect-AzAccount -ServicePrincipal -ApplicationId $applicationId -TenantId $tenantId -CertificatePath /cert.pfx
# Connect Graph separately for SPN
Connect-MgGraph -AppId $applicationId -Certificate $cert -TenantId $tenantId -NoWelcome
# Connect Maester for Copilot Studio only (Graph already connected)
Connect-Maester -Service Dataverse

The service principal must be registered as an Application User in Power Platform with a security role that grants read access to the bot, botcomponent, systemuser, and connectionreference tables.

The Azure DevOps security tests (AZDO.*) use the community ADOPS PowerShell module. This module is not bundled with Maester; install it separately and connect to your organization before running Invoke-Maester. If ADOPS is not installed or there is no active connection, the Azure DevOps tests are skipped.

Section titled “OAuth token-based authentication (recommended for automation)”

If you already have an authenticated Azure context (e.g., managed identity, workload identity federation, or Connect-AzAccount), you can use Get-AzAccessToken to obtain an OAuth token and pass it directly to Connect-ADOPS. This avoids the need to manage Personal Access Tokens.

#$tenantId = "xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx"
#$devOpsOrganization = "<your-azure-devops-organization>"
$DevOpsToken = ConvertFrom-SecureString `
-SecureString (Get-AzAccessToken -AsSecureString -TenantId $tenantId).Token `
-AsPlainText
Connect-ADOPS -Organization $devOpsOrganization -OAuthToken $DevOpsToken

For interactive sessions (e.g., local runs), use the standard sign-in flow:

Install-Module ADOPS -Scope CurrentUser
Connect-ADOPS -Organization <your-organization>

Some Azure DevOps tests require organization-level permissions such as Project Collection Administrator (e.g., AZDO.1030) or tenant-level permissions such as Azure DevOps Administrator (e.g., AZDO.1032–1036). See Manage policies as Administrator and the installation guide.