Unattended Exchange administration should not depend on a person’s password, an interactive sign-in prompt or a permanently signed-in administrator session. Exchange Online PowerShell supports app-only authentication using a Microsoft Entra ID application and a certificate. This gives scheduled reporting and administrative jobs their own identity, separate from the people who maintain them.
In Part 6 of the Microsoft 365 Architecture & Exchange Enterprise Deep Dive series, we turn that capability into an operational pattern. The objective is not simply to make Connect-ExchangeOnline succeed. It is to establish a controlled relationship between the application, its permissions, its private key and the workload that runs it. The examples use a Windows-hosted reporting task; the hosting and lifecycle principles also inform other supported automation designs.
1. Define the authentication boundary before building the job
Certificate-based app-only authentication allows an application to authenticate without a signed-in user. The application uses its private key to sign a client assertion, which Microsoft Entra ID validates against the certificate registered on the application. The resulting access token allows the application to connect to Exchange Online, subject to the permissions assigned to its identity.
This is distinct from Microsoft Entra certificate-based authentication for users. It is also distinct from Hybrid Modern Authentication, a hybrid mail-flow TLS certificate or a certificate installed on an Exchange server. Reusing terminology does not make these certificates interchangeable. Give the automation application its own credential and document the specific workload it serves.
The boundary matters particularly in hybrid environments. Connecting to Exchange Online with an application certificate does not authenticate the same script to an on-premises Exchange management endpoint. A workflow that administers both environments needs a separately supported authentication and authorisation design for each connection.
Define one operational purpose, such as mailbox inventory, rather than creating a general-purpose automation identity.
List every Exchange Online cmdlet and parameter the workflow needs before requesting permissions.
Check app-only support for those cmdlets. Microsoft documents limitations, including certain Microsoft 365 group operations; do not assume every interactive workflow can run unchanged.
Identify the execution host, runtime account, data destination and service owner before generating credentials.
2. Separate application authentication from Exchange authorisation
For the documented Exchange Online PowerShell app-only pattern, register an application in Microsoft Entra ID and add the Office 365 Exchange Online application permission Exchange.ManageAsApp. An authorised administrator must grant tenant-wide admin consent. This is an application permission, not a delegated permission acting on behalf of a signed-in administrator.
The application also needs Exchange authorisation. Microsoft documents supported Microsoft Entra role assignments and an Exchange role-group approach for assigning application permissions. Exchange.ManageAsApp is therefore not the complete permissions design: determine which management operations the application must actually perform and select the supported role assignment accordingly.
Exchange Administrator is a supported directory role for this connection pattern, but it is broad. Do not treat it as the default for a reporting task. Where narrower access is required, use the documented custom role-group approach and verify the effective permissions against the actual workload. Do not assume that a scope configured for a different application access model automatically limits Exchange Online PowerShell.
Record the application ID, tenant ID, initial tenant domain and enterprise application object ID. The app registration and enterprise application have different object IDs; use the identifier required by the relevant configuration step.
Remove unrelated API permissions and avoid adding Microsoft Graph permissions unless the workflow actually calls Microsoft Graph.
Test both permitted and prohibited actions. A successful inventory query alone does not demonstrate least privilege.
Keep production and development applications separate. This is an architectural control rather than a connection requirement: it allows permissions, certificate replacement and incident response to be managed without coupling experimental scripts to production access.
3. Create and register a certificate deliberately
The application registration receives the public certificate. The execution environment retains the private key. Uploading the public certificate does not give the application’s owners a copy of the private key, but anyone who can use that private key may be able to authenticate as the application. Protect access to the key as carefully as access to a privileged service credential.
Microsoft’s Exchange app-only guidance specifies that Cryptography Next Generation certificates are not supported for this scenario. Use a supported Cryptographic Service Provider certificate. The following Windows example selects a CSP explicitly, creates a non-exportable private key and exports only the public certificate. Its six-month validity is an example operational choice, not a Microsoft requirement.
$certificate = New-SelfSignedCertificate `
-Subject 'CN=SolutionSavy-ExchangeInventory' `
-CertStoreLocation 'Cert:\CurrentUser\My' `
-Provider 'Microsoft Enhanced RSA and AES Cryptographic Provider' `
-KeyAlgorithm RSA `
-KeyLength 2048 `
-HashAlgorithm SHA256 `
-KeySpec KeyExchange `
-KeyExportPolicy NonExportable `
-NotAfter (Get-Date).AddMonths(6)
$publicCertificatePath = Join-Path $env:TEMP 'ExchangeInventory.cer'
Export-Certificate -Cert $certificate -FilePath $publicCertificatePath
$certificate | Select-Object Subject, Thumbprint, NotAfter
$publicCertificatePathRun this under the intended execution identity if the job will use that identity’s CurrentUser certificate store. A certificate created in an administrator’s profile will not automatically appear in the scheduled task account’s store. Non-exportability also makes this a host-bound design: plan replacement on another host rather than assuming the private key can be transferred later.
Upload the exported .cer file under the app registration’s certificate credentials. Record its thumbprint and expiry in the workload inventory. A self-signed certificate is supported for this application authentication scenario; it is not being used to establish public HTTPS trust. If your organisation requires a centrally issued certificate, follow that issuance process while preserving the Exchange-specific compatibility requirements.
4. Build a predictable unattended PowerShell connection
Install and validate a supported ExchangeOnlineManagement module version on the execution host. Treat module changes as deployment changes: test the connection and workload before updating production. For certificate authentication, Connect-ExchangeOnline accepts the application ID, certificate information and organisation. Use the tenant’s initial .onmicrosoft.com domain for the Organisation value, as directed in Microsoft’s app-only guidance.
The CertificateThumbprint connection method is supported on Windows. The example below assumes the certificate is in the current user’s personal store and the task can access its private key. It validates those local prerequisites, connects, exports a mailbox inventory and disconnects. Replace the placeholders and choose an output directory with appropriate access controls.
$ErrorActionPreference = 'Stop'
Import-Module ExchangeOnlineManagement -ErrorAction Stop
$appId = '00000000-0000-0000-0000-000000000000'
$organisation = 'contoso.onmicrosoft.com'
$thumbprint = 'REPLACE_WITH_CERTIFICATE_THUMBPRINT'
$outputPath = 'C:\Automation\Output\MailboxInventory.csv'
$certificate = Get-Item "Cert:\CurrentUser\My\$thumbprint"
if (-not $certificate.HasPrivateKey) {
throw 'The configured certificate has no accessible private key.'
}
if ($certificate.NotBefore -gt (Get-Date) -or
$certificate.NotAfter -le (Get-Date)) {
throw 'The configured certificate is outside its validity period.'
}
$connected = $false
try {
Connect-ExchangeOnline `
-AppId $appId `
-CertificateThumbprint $thumbprint `
-Organization $organisation `
-ShowBanner:$false `
-ErrorAction Stop
$connected = $true
Get-EXOMailbox -ResultSize Unlimited |
Select-Object DisplayName, PrimarySmtpAddress, RecipientTypeDetails |
Export-Csv -Path $outputPath -NoTypeInformation
}
finally {
if ($connected) {
Disconnect-ExchangeOnline -Confirm:$false -ErrorAction SilentlyContinue
}
}Create the output directory beforehand and run the script using the actual scheduler identity during acceptance testing. A successful administrator-console test does not validate the scheduler’s certificate access, filesystem permissions or network path. The HasPrivateKey check is useful but does not replace a real authentication test under that identity.
This is a connection pattern, not a complete production reporting framework. Add structured job status, protected output storage and a clear failure signal for the scheduler. For sensitive workflows, publish the final output only after successful completion so downstream systems do not mistake a partial file for a complete report.
5. Choose the right host and rotate without interruption
Certificate credentials are useful when a workload needs app-only access from a host where managed identity is not suitable. However, Exchange Online PowerShell also supports managed identity connections in documented Azure hosting scenarios, including Azure Automation and Azure virtual machines. Where that model fits, consider it first: it removes the need for your team to distribute and rotate an application certificate. Exchange permissions still require deliberate configuration.
If certificates remain the appropriate choice, choose the loading method to match the platform. Thumbprint-based loading is Windows-specific. Connect-ExchangeOnline also supports a certificate object and certificate-file authentication. Avoid putting a PFX password in source code or alongside the PFX file; that simply recreates a stored-secret problem.
Design rotation as an overlapping change. Application registrations can hold multiple certificate credentials, allowing the replacement certificate to be registered before the previous one is removed. Do not rotate by deleting the working credential first.
Generate the replacement key and certificate in the approved execution environment.
Upload the new public certificate while retaining the existing application credential.
Update the job’s certificate reference and execute the full workload under its real runtime identity.
Confirm every execution host has moved to the new credential before removing the old application certificate and retiring the old private key.
Set an internal expiry-alert threshold that leaves time for testing and rollback. Include dormant jobs and disaster-recovery hosts in the inventory. A certificate that is only used during recovery still needs lifecycle ownership.
6. Troubleshoot by layer and use a release checklist
Start with the local execution layer: correct runtime account, certificate store, private-key access, validity dates and supported module. Then check application authentication: application ID, tenant, uploaded public certificate and Exchange.ManageAsApp admin consent. Finally, investigate Exchange authorisation and cmdlet support. Keeping these layers separate prevents unnecessary permission escalation when the real problem is an inaccessible key.
Microsoft Entra service principal sign-in logs provide evidence for application authentication attempts. Use available timestamps, status details and correlation information to investigate failed connections. These logs are not a transcript of Exchange commands. Maintain job-level records of the workload attempted, its result and its output location, while excluding tokens, private keys and sensitive report contents.
Before release, use this short checklist:
Purpose and ownership: one defined workload, named maintainers and a documented recovery path.
Permissions: required consent and Exchange roles only, with positive and negative authorisation tests.
Credential handling: supported certificate type, restricted private-key access and an inventoried expiry date.
Execution: tested under the scheduler identity with controlled module deployment and protected output.
Operations: visible job failures, appropriate sign-in investigation access and a tested rotation procedure.
If compromise is suspected, follow the incident-response process to contain the application identity, remove affected credentials and investigate its activity. Do not assume deleting a certificate credential immediately invalidates access tokens already issued. Coordinate containment with the team responsible for Microsoft Entra ID and Exchange permissions.
7. Conclusion: automate with an owned identity
Certificate-based authentication removes the dependency on a human sign-in, but it does not remove the need for identity governance. A reliable Exchange Online automation design combines a dedicated application, deliberately limited authorisation, protected private-key access and a rehearsed replacement process.
For hybrid organisations, keep cloud and on-premises authentication boundaries explicit. Prefer managed identity where Microsoft supports the hosting scenario and it meets the workload’s needs. Where certificates are appropriate, make ownership, monitoring and rotation part of the initial design—not maintenance tasks deferred until the first failed scheduled run.
App-only authentication for unattended scripts in Exchange Online PowerShell
Connect-ExchangeOnline: authentication methods and parameters
New-SelfSignedCertificate: certificate and private-key configuration
Get-EXOMailbox: mailbox inventory retrieval
Connect to Exchange Online PowerShell using managed identity
Microsoft Entra sign-in logs and sign-in categories
Originally published on Solution Savy. Need help with this? Book a consultation.




