Skip to main content

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 use login.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

The Invoke Exchange Online Command action runs commands available to the connected app, subject to its permissions and Microsoft’s app-only authentication support.

Get your credentials

Create an Entra ID app registration with Exchange.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.
1

Create the app registration

In your cloud’s Microsoft Entra admin center, search for App registrations, then select New registration. Choose Accounts in this organizational directory only, leave the Redirect URI blank, and register. From the app’s Overview page, copy the Application (client) ID and the Directory (tenant) ID.
2

Grant the Exchange Online permission

In the app registration, go to API permissions → Add a permission → APIs my organization uses → Office 365 Exchange Online → Application permissions, select Exchange.ManageAsApp, then select Add permissions and Grant admin consent. For GCC High, follow Microsoft’s app manifest instructions.
3

Create your credential (choose one method)

In the app registration, go to Certificates & secrets → New client secret. Copy the secret value immediately - Microsoft shows it only once.
4

Note your tenant domain

Confirm the Exchange Online organization domain with your administrator. For Commercial, use the primary .onmicrosoft.com domain, such as contoso.onmicrosoft.com, in Serval’s Organization field.
5

Find the Enterprise App Object ID

In your cloud’s Microsoft Entra admin center, go to Enterprise Applications (not App registrations), open your app, and copy its Object ID. You’ll enter this in Serval’s Enterprise App Object ID field.
6

Create an Exchange admin role group

Have an administrator with the Role Management role open Exchange admin center → Permissions → Admin roles → Add role group. Create a custom role group, for example Serval Recipient Management, and select the recipient write scope approved for your workflows.This must be an Exchange admin role group. Creating an ordinary Microsoft 365 group, security group, or distribution group doesn’t complete this step. See Microsoft’s role group setup instructions.
7

Select roles and confirm they were saved

On the Permission page of the role-group wizard, select the roles your workflows need. For example, for workflows that update existing mailboxes and manage distribution groups, select:
  • Mail Recipients for managing existing mailboxes.
  • Distribution Groups for managing distribution groups and their membership.
These are example roles, not a complete permission set for every workflow or health check. Have your administrator confirm command coverage, including 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.
Exchange.ManageAsApp and admin consent don’t grant the workflow’s commands by themselves. Exchange PowerShell management roles determine command access. This setup uses an approved custom role group. Other assigned roles also contribute permissions, so adding a scoped group doesn’t restrict a broader grant.

Connect in Serval

1

Open the Exchange Online connect form

In Serval, open Integrations, find Exchange Online, and start a new connection.
2

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.
Cloud environment and Organization select the connection’s destination. Saving these values doesn’t verify that they belong to the configured tenant.
3

Choose an Authentication Method

Select Client Secret (the default) or Certificate (PEM). Only the credential field for the selected method appears.
  • Client Secret: Paste the secret value from your app registration.
  • Certificate (PEM): Paste the combined PEM certificate and private key.
4

Name the connection (optional)

Use Instance Name (Optional) to describe the app’s purpose, such as “Recipient management” or “Mailbox settings”. If you leave it blank, Serval uses the Organization value followed by the first eight characters of the App (Client) ID, such as contoso.onmicrosoft.com (bbbbbbbb).
5

Save, then set up access

After saving, open the connection’s settings and select Set up access in the Exchange Online access card. In the dialog, enter the Approved Exchange role group name and Enterprise App Object ID. The role group must already exist. Enter Organization Management only if its broad permissions are approved for this app.Select Generate setup script to review the script, then Copy setup script. Use Edit details if you need to change either field and generate the script again.Have an Exchange administrator run the reviewed script in PowerShell, signing in to this connection’s Microsoft 365 tenant. Generating or copying the script doesn’t run it. The script registers this app’s service principal if needed, adds it to the named role group if needed, and disconnects. It doesn’t create a role group or define its commands or scope.
Exchange PowerShell role groups and recipient write scopes are separate from Application RBAC permissions for Graph and EWS. For example, Application Exchange Full Access grants Graph mailbox API access, not Exchange PowerShell commands. A write scope limits modifications; it doesn’t establish an equivalent read boundary.
Credential rotation: keep the same app and tenant, and paste the complete new Client Secret or Certificate. Blank or masked credential values retain the saved credential. When switching authentication methods, enter the new credential. Use a new connection and update the appropriate workflow bindings when changing apps or tenants. New connections keep their tenant and app identity fixed; older connections saved under a label retain their existing editing behavior.

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.
Keep selectors inline as shown. Type aliases, bare selector imports from .../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: Mailbox and distribution group checks can succeed with a sample count of zero. A check that returns no structured result fails; inspect its error before changing permissions. An unavailable check command can be outside the app’s approved scope; it doesn’t establish that the app has no management roles. In Health Checks, turn off only checks that an Exchange administrator confirms are intentionally outside that scope. Unknown or a disabled check doesn’t confirm that a workflow operation works. Validate each required operation against an approved test recipient, including a recipient outside the intended write scope when testing scope restrictions.
Successful health checks verify those read commands. They don’t verify every workflow action, recipient write scope, or Microsoft 365 (Graph) connection.

Gotchas and troubleshooting

Check the command name, app-only support, and the app’s approved Exchange PowerShell role group. An unavailable command doesn’t prove that every management role is missing. If Exchange explicitly reports no management role assignment, ask an Exchange administrator to verify the service principal and its approved role group. Review health check commands separately: Get-OrganizationConfig, Get-Mailbox, and Get-DistributionGroup.
Confirm the app has the Exchange.ManageAsApp application permission with admin consent granted, then run the post-save setup script. Make sure you used the Enterprise Application Object ID, not the App registration’s Object ID. Microsoft can take a little while to apply new permissions and role assignments, so a just-fixed connection may keep failing briefly before it starts working.
Connect and authorize each integration separately. You can use the same Entra app registration if it has the required permissions for both, or separate registrations with different scopes.
Microsoft Graph treats distribution groups and mail-enabled security groups as read-only and doesn’t support dynamic distribution groups. Use Exchange Online to manage them. Plain distribution groups have dedicated Serval actions; use Invoke Exchange Online Command for operations without a dedicated action. See Microsoft’s group types overview.
Serval requires the certificate and the private key combined in a single paste - the text must contain both a certificate block and a private key block. Upload only the certificate file to Entra, but paste the combined certificate-plus-key file into Serval.
Changing the Authentication Method on an existing connection requires the new credential in the same save - otherwise the save fails with an error that includes “Client Secret is required when switching to client secret authentication” or “Certificate (PEM) is required when switching to certificate authentication”. Switching wipes the previously stored secrets, and even within the same method, saving a new client secret clears any stored certificate (and vice versa).
Every action runs in a fresh session - Serval connects to Exchange Online at the start and disconnects at the end, with a default timeout of 120 seconds. Scripts that exceed the timeout are forcibly stopped and surface as an error. For long operations (large-tenant listings, bulk updates), raise the timeout setting on the Invoke Exchange Online Command action - the dedicated actions don’t expose a timeout control.
The Exchange Online module can write formatting escape codes to the console. Read results from the action’s structured 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.
Exchange Online is action-only: there are no installable workflow templates, no synced entities, and no background data ingestion. Everything happens on demand when a workflow runs an Exchange Online action or a health check fires.

Need help? Contact support@serval.com for assistance with your Exchange Online integration.