Guide

Exchange CLI: Read Emails from Terminal

Use an Exchange CLI to list, search, and read Exchange Online or on-prem email from terminal. Exchange email access has three paths right now: EWS, PowerShell modules, or the Microsoft Graph API. The CLI collapses that setup behind one command surface.

Written by Caleb Geene Director, Site Reliability Engineering

Reviewed by Hazik

VerifiedCLI 3.1.1 · Exchange · last tested April 11, 2026

How do you use an Exchange CLI from terminal?

Connect Exchange Online or on-prem Exchange once, then run nylas email list, nylas email search, and nylas email read. This gives Exchange a terminal workflow without writing EWS SOAP, Exchange PowerShell scripts, or Microsoft Graph API clients.

EWS is dying for Exchange Online. Here's what that means.

Microsoft announced the deprecation of Exchange Web Services for Exchange Online in message center post MC862873. The timeline: EWS will be fully disabled for Exchange Online tenants by October 2026. According to Microsoft's migration guidance, all EWS integrations must move to Microsoft Graph API before that date.

This affects roughly 345 million paid Microsoft 365 seats worldwide (Microsoft FY2024 earnings). If you have scripts that call FindItem, GetItem, or SyncFolderItems against Exchange Online, they'll break.

On-premises Exchange Server is not affected. EWS continues to work on Exchange Server 2016 and 2019. But if you're running a hybrid deployment, your cloud mailboxes will lose EWS access while your on-prem mailboxes keep it.

The Graph API alternative isn't simple

Microsoft Graph API is Microsoft's official replacement for EWS on Exchange Online, but it adds significant setup overhead. A working Graph mail integration requires Azure AD app registration, OAuth2 flow configuration, token management, and pagination handling -- roughly 6 steps before you can read a single message.

  1. Register an application in Azure Active Directory
  2. Configure API permissions (Mail.Read, Mail.ReadWrite, or Mail.Read.Shared for shared mailboxes)
  3. Set up an OAuth2 authorization flow with redirect URIs
  4. Handle token acquisition, caching, and refresh (access tokens expire in 3600 seconds)
  5. Implement the Graph API calls with proper pagination using $top and $skip
  6. Parse the JSON response format, which differs from EWS XML

For a single GET /me/messages call, you need approximately 80 lines of code in Python or Node.js, not counting error handling or token refresh logic.

1. Install the Nylas CLI

The Nylas CLI installs in under 2 minutes on macOS, Linux, or Windows and connects to Exchange Online and on-premises Exchange Server without requiring Azure AD app registration or the ExchangeOnlineManagement PowerShell module. Homebrew is the fastest method on macOS and Linux.

The Homebrew formula pulls the latest release binary (currently around 25 MB) from GitHub, verifies a SHA-256 checksum, and places the nylas binary on your PATH.

brew install nylas/nylas-cli/nylas

Other install methods (shell script, PowerShell, Go) are in the getting started guide.

2. Connect your Exchange account

Connecting an Exchange account to the Nylas CLI takes about 3 minutes. The process works for both Exchange Online (Microsoft 365) and on-premises Exchange Server, covering the full range of Exchange deployments that span an estimated 400,000 organizations worldwide.

Create an application at dashboard-v3.nylas.com and connect your Exchange account. Then configure authentication locally:

nylas auth config
# Paste your API key when prompted

# Verify the connection
nylas auth whoami
# => Authenticated as you@company.com (Exchange)

3. List your Exchange inbox

The nylas email list command retrieves messages from an Exchange mailbox in a single terminal call. It returns the 10 most recent messages by default, with subject, sender, date, and read status. The same command works identically across Exchange Online and on-premises Exchange Server.

The CLI formats output as a human-readable table by default or as structured JSON when you pass --json. Filtering by unread status avoids pulling all messages, which matters for Exchange mailboxes that can hold over 50 GB under the default Microsoft 365 quota.

# List recent messages
nylas email list

# Show only unread messages
nylas email list --unread

# Limit to 20 results
nylas email list --limit 20

Exchange Online vs on-premises: what differs

The Nylas CLI uses the same nylas email list command for both Exchange Online and on-premises Exchange Server. Behind the scenes, Nylas routes Exchange Online requests through the Microsoft Graph API and on-premises requests through EWS with autodiscover. This distinction matters because Microsoft still supports roughly 30,000 on-premises Exchange Server deployments alongside its cloud offering.

AspectExchange Online (M365)On-premises Exchange
Protocol used by NylasMicrosoft Graph APIEWS with autodiscover
AuthenticationOAuth2 via Microsoft identity platformNTLM or Basic Auth
Admin consent needed?Only if tenant restricts third-party appsNo (user-level auth)
AutodiscoverCloud-based (login.microsoftonline.com)DNS SRV or SCP lookup
EWS deprecation impactNylas migrated to Graph automaticallyNot affected
Hybrid deploymentsBoth mailbox types work through the same CLI commands

Shared mailboxes and room calendars

The Nylas CLI accesses shared mailboxes, room mailboxes, and equipment mailboxes by connecting each as a separate grant in the Nylas dashboard. Exchange environments typically have three special mailbox types: shared mailboxes for teams (support@, sales@), room mailboxes for meeting rooms, and equipment mailboxes. About 67% of Exchange Online organizations use at least one shared mailbox, according to Microsoft's 365 admin adoption data.

The --grant flag switches between connected mailboxes without re-authenticating. Each shared mailbox is connected once in the dashboard and then accessible by its email address.

# Connect a shared mailbox as a separate grant in the Nylas dashboard,
# then switch between personal and shared mailboxes:
nylas email list --grant "support@company.com" --limit 10

# Check another shared mailbox
nylas email list --grant "sales@company.com" --unread

# Search across a specific shared mailbox
nylas email search "refund request" --grant "support@company.com"

For room mailboxes, the pattern is the same. Connect the room mailbox as a grant and list its messages to see booking confirmations and meeting requests.

PowerShell comparison: Get-ExoMailbox vs Nylas CLI

The ExchangeOnlineManagement PowerShell module requires admin credentials and role-based access control permissions, while the Nylas CLI works with user-level OAuth2 credentials and needs no module installation. PowerShell's New-ComplianceSearch cmdlet alone requires the Compliance Search role, which fewer than 5% of users in a typical Exchange tenant have assigned.

The side-by-side comparison covers two common tasks: listing folder statistics and searching messages. The PowerShell path requires module installation and admin-level connection, while the Nylas CLI runs with a single command and user-level access.

# PowerShell: List mailbox contents (requires ExchangeOnlineManagement module)
# Install-Module ExchangeOnlineManagement
# Connect-ExchangeOnline -UserPrincipalName admin@company.com
# Get-MailboxFolderStatistics -Identity user@company.com |
#   Select-Object Name, ItemsInFolder

# Nylas CLI: Same information, no admin module needed
nylas folder list
# Shows folder names and message counts

# PowerShell: Search messages (requires Compliance Search role)
# New-ComplianceSearch -Name "Q1 Reports" \
#   -ExchangeLocation user@company.com \
#   -ContentMatchQuery "subject:Q1 AND sent>=2026-01-01"
# Start-ComplianceSearch -Identity "Q1 Reports"

# Nylas CLI: Search without admin privileges
nylas email search "subject:Q1" --limit 20

The difference: PowerShell's Get-ExoMailbox and New-ComplianceSearch require the ExchangeOnlineManagement module, admin credentials, and role-based access control permissions. The Nylas CLI works with user-level OAuth2 credentials.

EWS migration scenarios

Organizations migrating off EWS before the October 2026 deadline face three common integration patterns: inbox monitoring, compliance searches, and distribution list tracking. Microsoft estimates that over 100,000 EWS applications need to migrate to Graph API or an alternative. The Nylas CLI covers each pattern with standard commands that work across Exchange Online and on-premises deployments.

Automated inbox monitoring

EWS pattern: SubscribeToStreamingNotifications or polling with FindItem in a loop. Graph replacement: /subscriptions endpoint with webhooks. Nylas CLI approach:

# Poll for new messages in a cron job or CI pipeline
nylas email list --unread --json | jq length
# Returns count of unread messages

# Get unread messages with full metadata
nylas email list --unread --json --limit 50 | \
  jq -r '.[] | "\(.received_at) \(.from[0].email): \(.subject)"'

Compliance and audit searches

EWS pattern: SearchMailboxes with discovery management role. In Exchange Online, Microsoft replaced this with the Purview compliance portal. The CLI handles standard user-scoped searches:

# Search for sensitive terms across your mailbox
nylas email search "confidential" --json --limit 100 | \
  jq '[.[] | {date: .date, from: .from[0].email, subject: .subject}]'

# Filter by date range for audit windows
nylas email search "after:2026-01-01 before:2026-03-31" --json | \
  jq length
# => 847 messages in Q1 2026

Distribution list monitoring

Exchange distribution lists (DLs) and Microsoft 365 Groups both deliver to member mailboxes. To track messages sent to a specific DL:

# Find emails sent to the engineering distribution list
nylas email search "to:engineering@company.com" --limit 20

# Count DL traffic over the past month
nylas email search "to:all-hands@company.com after:2026-03-01" --json | \
  jq length

Exchange folder structure

Exchange mailboxes use a folder hierarchy distinct from Gmail labels or Yahoo folders. A default Exchange Online mailbox ships with 13 system folders including Inbox, Sent Items, Deleted Items, Junk Email, Conversation History, and Clutter. Exchange also supports Public Folders shared across an organization and In-Place Archive mailboxes for long-term retention.

The nylas folder list command returns every folder in the mailbox with its display name and message count. Filtering messages by folder with --folder lets you target Exchange-specific folders that don't exist in other providers.

# List all folders in your Exchange mailbox
nylas folder list

# Common Exchange-specific folders
nylas email list --folder "Inbox"
nylas email list --folder "Sent Items"
nylas email list --folder "Deleted Items"
nylas email list --folder "Junk Email"

# Check Conversation History (Skype/Teams saved messages)
nylas email list --folder "Conversation History" --limit 5

EWS vs Graph API vs Nylas CLI

Three approaches exist for programmatic Exchange email access: EWS (deprecated for Exchange Online in October 2026), the Microsoft Graph API, and the Nylas CLI. Setup time ranges from approximately 5 minutes with the CLI to 60 minutes with Graph API, primarily because Graph requires Azure AD app registration and OAuth2 configuration. The following comparison covers 9 dimensions.

ConcernEWSMicrosoft GraphNylas CLI
Setup time~30 min (SOAP endpoint config)~60 min (Azure AD app + OAuth2)~5 min (dashboard + API key)
Lines of code~50 (SOAP XML)~80 (REST + auth)0
AuthenticationNTLM, Basic, or OAuth2OAuth2 onlyHandled by Nylas
Exchange Online supportUntil Oct 2026YesYes
On-prem supportYesNoYes (via EWS)
Shared mailbox supportYes (impersonation)Yes (Mail.Read.Shared)Yes (multi-grant)
PaginationIndexedPageItemView$top / $skip / @odata.nextLink--limit flag
Search syntaxAQS / RestrictionType SOAP$search / $filter ODatanylas email search
Deprecation riskHigh (Oct 2026)LowNone (Nylas abstracts)

JSON output for Exchange automation

The --json flag on nylas email list outputs structured JSON that pipes directly into jq, Python, or any scripting language. Each message object includes over 15 fields: subject, from, to, cc, bcc, date, received_at, thread_id, labels, folders, and more. This makes it straightforward to build cron-based monitors, compliance exports, or alerting scripts for Exchange mailboxes.

Three common Exchange automation patterns follow: daily unread monitoring for shared mailboxes, sender auditing across the last 100 messages, and external domain detection.

# Daily unread count for a shared mailbox (run via cron)
COUNT=$(nylas email list --unread --json --grant "support@company.com" | jq length)
echo "$(date +%Y-%m-%d) support@ unread: $COUNT" >> /var/log/mailbox-stats.log

# Extract all senders from the last 100 messages for audit
nylas email list --limit 100 --json | \
  jq -r '[.[] | .from[0].email] | unique | .[]' | sort

# Flag messages from external domains
DOMAIN="company.com"
nylas email list --limit 50 --json | \
  jq --arg d "$DOMAIN" '[.[] | select(.from[0].email | endswith($d) | not)]' | \
  jq length | xargs -I{} echo "External messages: {}"

Next steps