Guide
Send-MailMessage Replacement Guide
Microsoft deprecated Send-MailMessage because it can't negotiate TLS securely. Basic Auth shuts down April 30, 2026, breaking scripts that still use it. This guide shows side-by-side migration examples for every common email pattern -- basic sends, attachments, credentials, SMTP relay, HTML, and bulk loops. Works with Gmail, Outlook, Exchange, Yahoo, iCloud, and IMAP.
Written by Nick Barraclough Product Manager
Reviewed by Qasim Muhammad
Why Send-MailMessage is deprecated
Microsoft deprecated Send-MailMessage in PowerShell 7.0 (official docs). The underlying System.Net.Mail.SmtpClient class cannot negotiate TLS securely. The problems:
- Insecure TLS negotiation -- SmtpClient does not support modern TLS handshakes reliably
- Credentials in scripts -- SMTP passwords end up hardcoded in
-Credentialor stored inPSCredentialobjects - No OAuth2 -- Gmail and Outlook require OAuth2 for programmatic access; Send-MailMessage only supports basic auth
- Provider lock-in -- SMTP settings differ per provider; switching means rewriting connection code
One-time setup
Before migrating your scripts, install Nylas CLI and authenticate once:
# Install Nylas CLI (one-liner for PowerShell)
irm https://cli.nylas.com/install.ps1 | iex
# Or install with Go (requires Go 1.23+)
# go install github.com/nylas/cli/cmd/nylas@latest# Authenticate your mailbox
nylas auth config
# Paste your API key from dashboard-v3.nylas.com
# Verify
nylas auth whoami
# => Authenticated as you@company.com (Google Workspace)That's it. No SMTP server, no port numbers, no credentials in your scripts.
Pattern 1: Basic email send
Before (Send-MailMessage)
Send-MailMessage `
-From "you@company.com" `
-To "colleague@company.com" `
-Subject "Quarterly report" `
-Body "Please review the Q4 numbers." `
-SmtpServer "smtp.office365.com" `
-Port 587 `
-UseSsl `
-Credential (Get-Credential)After (Nylas CLI)
nylas email send `
--to "colleague@company.com" `
--subject "Quarterly report" `
--body "Please review the Q4 numbers." `
--yesNo -From (uses the authenticated account). No -SmtpServer, no -Port, no -Credential. The CLI handles all of this.
Pattern 2: Send with attachment
Before (Send-MailMessage)
Send-MailMessage `
-From "you@company.com" `
-To "client@example.com" `
-Subject "Invoice attached" `
-Body "Please find the March invoice." `
-Attachments "C:Reportsinvoice-march.pdf" `
-SmtpServer "smtp.gmail.com" `
-Port 587 `
-UseSsl `
-Credential $credAfter (Nylas CLI)
nylas email send `
--to "client@example.com" `
--subject "Invoice attached" `
--body "Please find the March invoice." `
--attach "C:Reportsinvoice-march.pdf" `
--yesPattern 3: Send with stored credentials
Before (Send-MailMessage)
# Credentials stored in a file or prompted every time
$cred = Import-Clixml -Path "C:Scriptssmtp-cred.xml"
# Or: $cred = Get-Credential
Send-MailMessage `
-From "alerts@company.com" `
-To "oncall@company.com" `
-Subject "Server alert" `
-Body "CPU above 90%." `
-SmtpServer "smtp.office365.com" `
-Port 587 `
-UseSsl `
-Credential $credAfter (Nylas CLI)
# No credentials in the script -- API key stored securely by the CLI
nylas email send `
--to "oncall@company.com" `
--subject "Server alert" `
--body "CPU above 90%." `
--yesThe Nylas CLI stores your API key in your OS keychain (Windows Credential Manager). No .xml credential files, no plaintext passwords in scripts.
Pattern 4: Send via SMTP relay
Before (Send-MailMessage)
# Internal relay -- no auth, no TLS
Send-MailMessage `
-From "noreply@internal.corp" `
-To "team@company.com" `
-Subject "Build complete" `
-Body "Build #1234 succeeded." `
-SmtpServer "relay.internal.corp" `
-Port 25After (Nylas CLI)
# OAuth2 authenticated, TLS encrypted, no internal relay needed
nylas email send `
--to "team@company.com" `
--subject "Build complete" `
--body "Build #1234 succeeded." `
--yesInternal SMTP relays are a security risk -- unauthenticated, often unencrypted, and a common target for lateral movement. Nylas CLI uses OAuth2 and TLS by default.
Pattern 5: HTML email
Before (Send-MailMessage)
$htmlBody = @"
<h1>Weekly Report</h1>
<p>Here are this week's metrics:</p>
<ul>
<li>Deployments: 12</li>
<li>Incidents: 0</li>
</ul>
"@
Send-MailMessage `
-From "reports@company.com" `
-To "team@company.com" `
-Subject "Weekly report" `
-Body $htmlBody `
-BodyAsHtml `
-SmtpServer "smtp.office365.com" `
-Port 587 `
-UseSsl `
-Credential $credAfter (Nylas CLI)
$htmlBody = @"
<h1>Weekly Report</h1>
<p>Here are this week's metrics:</p>
<ul>
<li>Deployments: 12</li>
<li>Incidents: 0</li>
</ul>
"@
nylas email send `
--to "team@company.com" `
--subject "Weekly report" `
--body $htmlBody `
--yesNo -BodyAsHtml flag needed. The CLI auto-detects HTML content and sets the correct MIME type.
Pattern 6: Bulk send loop
Before (Send-MailMessage)
$cred = Import-Clixml -Path "C:Scriptssmtp-cred.xml"
Import-Csv -Path ".contacts.csv" | ForEach-Object {
Send-MailMessage `
-From "onboarding@company.com" `
-To $_.Email `
-Subject "Welcome, $($_.Name)!" `
-Body "Your account is ready." `
-SmtpServer "smtp.office365.com" `
-Port 587 `
-UseSsl `
-Credential $cred
Start-Sleep -Seconds 2
}After (Nylas CLI)
Import-Csv -Path ".contacts.csv" | ForEach-Object {
nylas email send `
--to $_.Email `
--subject "Welcome, $($_.Name)!" `
--body "Your account is ready." `
--yes
Start-Sleep -Seconds 2
}No credential setup, no SMTP config. The loop body is half the size and twice as secure.
Side-by-side comparison
| Feature | Send-MailMessage | Nylas CLI |
|---|---|---|
| TLS security | Broken (deprecated) | TLS 1.2+ enforced |
| Authentication | Basic auth / app passwords | OAuth2 |
| Credentials in scripts | Yes (PSCredential / XML) | No (OS keychain) |
| Gmail support | Requires app password | OAuth2 built-in |
| Outlook / M365 support | Basic auth (being disabled) | OAuth2 built-in |
| HTML body | -BodyAsHtml flag | Auto-detected |
| Attachments | -Attachments | --attach |
| Email scheduling | Not supported | --schedule |
| Read inbox | Not supported | nylas email list |
| JSON output | Not supported | --json |
| Calendar access | Not supported | nylas calendar |
Frequently asked questions
Why is Send-MailMessage deprecated?
Microsoft deprecated it in PowerShell 7.0 because the underlying System.Net.Mail.SmtpClient cannot negotiate TLS securely. Microsoft recommends using third-party libraries instead.
What is the best replacement for Send-MailMessage?
Nylas CLI replaces Send-MailMessage with a single command. It handles OAuth2, TLS, and provider differences automatically. No SMTP credentials in your scripts, no provider-specific configuration.
Do I need to change my PowerShell scripts?
Yes, but the migration is straightforward. Replace each Send-MailMessage call with nylas email send and map the parameters: -To becomes --to, -Subject becomes --subject, -Body becomes --body, -Attachments becomes --attach.
Does Nylas CLI support all Send-MailMessage features?
Yes, and more. It supports HTML bodies (auto-detected), file attachments, CC/BCC, and multiple recipients. It also adds features Send-MailMessage never had: OAuth2, email scheduling, open/click tracking, JSON output, and inbox read access.
Next steps
- Replace Send-MgUserMessage -- migrating from the newer Graph PowerShell cmdlets instead?
- Send email from PowerShell -- advanced patterns, scheduling, and scripting
- Read and search email in PowerShell -- list unread, search by sender, export to CSV
- Download email attachments in PowerShell -- filter by type, batch download, rename
- Automated email reports with PowerShell -- CSV reports, scheduled sends, templates
- Manage Office 365 email from PowerShell -- read, search, and organize your M365 inbox
- Full command reference -- every flag and subcommand documented