About Exchange Online
Exchange Online is Microsoft’s cloud email and calendaring service, part of Microsoft 365. The Serval integration runs Exchange Online PowerShell to manage mailboxes, distribution groups, mail-enabled security groups, and dynamic distribution groups. It is a separate integration from Microsoft Graph (Microsoft 365): teams using both need both connected. Commercial connections uselogin.microsoftonline.com for sign-in and outlook.office365.com for Exchange Online. GCC High uses login.microsoftonline.us and outlook.office365.us. See Microsoft’s Exchange Online connection environments.
Authentication: Microsoft Entra ID app registration, using either a Client Secret or a Certificate (PEM). Both methods use app-only access tokens. Choose the method approved for your app registration.
Data sync: On-demand only. There is no background sync, entity ingestion, or scheduled polling - each action opens a fresh Exchange Online session on the Serval worker, runs, and disconnects.
What the Exchange Online integration enables
Get your credentials
Create an Entra ID app registration withExchange.ManageAsApp and admin consent. Have an Exchange administrator prepare a custom PowerShell role group for the commands and recipient write scope your workflows need. Serval generates a script to register the app in Exchange and add it to that existing group. See Microsoft’s app-only authentication guide.
Create the app registration
Grant the Exchange Online permission
Create your credential (choose one method)
- Client Secret
- Certificate (PEM)
Note your tenant domain
.onmicrosoft.com domain, such as contoso.onmicrosoft.com, in Serval’s Organization field.Find the Enterprise App Object ID
Create an Exchange admin role group
Select roles and confirm they were saved
- Mail Recipients for managing existing mailboxes.
- Distribution Groups for managing distribution groups and their membership.
Get-OrganizationConfig if you plan to use the Get Organization Config health check.Continue through Admins to Review and finish, review the selections, and select Add role group. Serval’s setup script adds the app’s service principal later.Before running that script, reopen the group under Admin roles. Confirm the selected roles on the Permission tab and the write scope on the General tab. If you change the roles, select Save and reopen the group to confirm they persisted. Copy the group’s exact name for Serval’s Approved Exchange role group field.Connect in Serval
Open the Exchange Online connect form
Enter your app details
- Cloud environment: Select Commercial or GCC High (US Government) for your tenant.
- App (Client) ID: Enter the app registration’s Application (client) ID.
- Tenant (Directory) ID: Enter the app registration’s Directory (tenant) ID.
- Organization: Enter the Microsoft 365 tenant domain. Serval trims whitespace and lowercases it.
Choose an Authentication Method
- Client Secret: Paste the secret value from your app registration.
- Certificate (PEM): Paste the combined PEM certificate and private key.
Name the connection (optional)
contoso.onmicrosoft.com (bbbbbbbb).Save, then set up access
Use multiple scoped connections
Connect each Entra app separately and give it a name that describes its purpose. Each saved connection has a selector that workflows can bind to. Keep existing saved selectors when updating credentials; don’t reconstruct them from a tenant domain or app ID. Use the saved connection’s settings to rename it, reconnect it, or change its cloud environment. A fresh Connect for an already connected app with a different cloud is refused. In TypeScript workflows, declare each selector directly in the workflow’s context type and pass the named connection to each action. Catalyst receives the saved selectors alongside the connection names; ask Catalyst to bind the named connections. New selectors contain the lowercase, hyphenated Tenant (Directory) ID and App (Client) ID, joined by/. Earlier connections keep their saved labels. Replace the two saved-key placeholders below with the connections’ actual selectors. This workflow returns a mailbox and a distribution group; Get Distribution Group also requires permission to list that group’s members.
.../sdk/context, and deeper namespace references aren’t extracted as app bindings, even when TypeScript accepts them. Don’t mix a named target with the unbound Exchange context in the same workflow.
Use distinct aliases for distinct purposes. Two aliases can use the same saved selector when one app serves both purposes. Don’t reuse one alias for different selectors. Serval doesn’t choose an app based on the command’s permissions, so use explicit bindings for scoped apps.
When you test an unbound Exchange workflow through Catalyst and your team owns multiple Exchange connections, choose a connection before the run can start. This check uses the version being run, including historical versions and edits to temporary workflows, and runs again at startup in case the draft changed after your request. A version with explicit bindings or no Exchange use doesn’t need this choice.
Other runs can still use the oldest available connection if neither the code nor the run selects one. Bind scoped workflows explicitly before using them with multiple connections.
Verifying the connection
Serval runs three health checks against your tenant:Gotchas and troubleshooting
Authentication succeeds but a cmdlet "is not recognized"
Authentication succeeds but a cmdlet "is not recognized"
Get-OrganizationConfig, Get-Mailbox, and Get-DistributionGroup.Exchange Online and Microsoft 365 (Graph) are separate integrations
Exchange Online and Microsoft 365 (Graph) are separate integrations
Some group types can only be created or changed through this integration
Some group types can only be created or changed through this integration
Certificate is rejected with "Invalid certificate PEM"
Certificate is rejected with "Invalid certificate PEM"
Switching authentication methods requires the new credential up front
Switching authentication methods requires the new credential up front
Long-running operations time out at 120 seconds
Long-running operations time out at 120 seconds
Script output looks garbled, or results seem empty
Script output looks garbled, or results seem empty
json result. PowerShell success-stream output is serialized automatically; json is null when the script produces no output. $ErrorActionPreference is set to Stop, so PowerShell errors stop the script.No pre-built workflows or synced data for this integration
No pre-built workflows or synced data for this integration
Need help? Contact support@serval.com for assistance with your Exchange Online integration.

