Guide

List Exchange Emails from Terminal

Exchange email access has three paths right now: EWS (deprecated for Exchange Online in October 2026), PowerShell modules (require admin privileges), or the Microsoft Graph API (requires Azure AD app registration and permission scoping). The Nylas CLI sidesteps all three. It works across Gmail, Outlook, Exchange, Yahoo, iCloud, and IMAP providers through a single interface.

Written by Caleb Geene Director, Site Reliability Engineering

Reviewed by Hazik

VerifiedCLI 3.1.1 · Exchange · last tested April 11, 2026

EWS is dying. 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's recommended replacement is the Microsoft Graph API. Here's what that requires:

  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

brew install nylas/nylas-cli/nylas

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

2. Connect your Exchange account

Head to dashboard-v3.nylas.com, create an application, and connect your Exchange account. Nylas supports both Exchange Online (Microsoft 365) and on-premises Exchange Server. Then configure authentication:

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

# 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 CLI command is identical for both. What changes is what Nylas does behind the scenes:

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

Exchange environments typically have three types of special mailboxes: shared mailboxes (used by teams like support@ or sales@), room mailboxes (for meeting rooms), and equipment mailboxes (for projectors, vehicles). About 67% of Exchange Online organizations use at least one shared mailbox, according to Microsoft's 365 admin adoption data.

# 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

Exchange admins often reach for PowerShell's Exchange Online module. Here's how the two approaches compare for common tasks:

# 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

If you're moving off EWS before the October 2026 deadline, here are the common patterns and how the Nylas CLI handles each:

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 uses a different folder hierarchy than Gmail or Yahoo. The default mailbox includes folders like Inbox, Sent Items, Deleted Items, Junk Email, and Conversation History. Exchange also supports Public Folders and Archive mailboxes (In-Place Archive).

# 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

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

Pipe Exchange mailbox data into scripts for reporting, compliance, or alerting:

# 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