Guide
Monitor Your Inbox with PowerShell
Build inbox monitoring and alerting scripts using PowerShell and Nylas CLI. Poll for new emails, watch for specific senders or subjects, detect OTP codes, track unread counts, and trigger actions like Teams webhooks or Windows desktop notifications -- all from a PowerShell script.
Prerequisites
You need Nylas CLI installed and authenticated. PowerShell 5.1+ (included with Windows 10/11) or PowerShell 7+ (cross-platform) both work.
# Install Nylas CLI (one-liner for PowerShell)
irm https://cli.nylas.com/install.ps1 | iex
# Or install with Go (requires Go 1.21+)
# go install github.com/nylas/cli/cmd/nylas@latest
# Authenticate with your email provider
nylas auth loginBasic polling loop
The simplest monitor polls for unread emails at a fixed interval and prints new messages to the console. Nylas CLI returns JSON, and PowerShell's ConvertFrom-Json turns it into objects natively.
# monitor-inbox.ps1 -- Basic email polling loop
$previousIds = @()
while ($true) {
$emails = nylas email list --unread --json --limit 20 | ConvertFrom-Json
foreach ($email in $emails) {
if ($email.id -notin $previousIds) {
Write-Host "NEW: $($email.subject) — from $($email.from)" -ForegroundColor Green
}
}
$previousIds = $emails | ForEach-Object { $_.id }
Start-Sleep -Seconds 30
}Detecting new messages with Compare-Object
For more robust change detection, use Compare-Object to diff the current email list against the previous snapshot. This catches new arrivals and removed messages (e.g., read or deleted elsewhere).
# monitor-diff.ps1 -- Detect new and removed emails
$previous = @()
while ($true) {
$current = nylas email list --unread --json --limit 50 | ConvertFrom-Json
if ($previous.Count -gt 0) {
$diff = Compare-Object -ReferenceObject $previous -DifferenceObject $current `
-Property id -PassThru
$newEmails = $diff | Where-Object { $_.SideIndicator -eq "=>" }
$removedEmails = $diff | Where-Object { $_.SideIndicator -eq "<=" }
foreach ($email in $newEmails) {
Write-Host "[+] New: $($email.subject) from $($email.from)" -ForegroundColor Cyan
}
foreach ($email in $removedEmails) {
Write-Host "[-] Gone: $($email.subject)" -ForegroundColor DarkGray
}
}
$previous = $current
Start-Sleep -Seconds 30
}Watch for specific senders or subjects
Filter incoming emails by sender or subject pattern. This example watches for emails from a specific domain and emails with "urgent" in the subject.
# watch-sender.ps1 -- Alert on emails from specific senders
$watchSenders = @("*@accounting.example.com", "*@alerts.pagerduty.com")
$watchSubjects = @("*urgent*", "*action required*", "*password reset*")
$seenIds = @()
while ($true) {
$emails = nylas email list --unread --json --limit 20 | ConvertFrom-Json
foreach ($email in $emails) {
if ($email.id -in $seenIds) { continue }
$senderMatch = $watchSenders | Where-Object { $email.from -like $_ }
$subjectMatch = $watchSubjects | Where-Object { $email.subject -like $_ }
if ($senderMatch -or $subjectMatch) {
Write-Host "ALERT: $($email.subject) from $($email.from)" `
-ForegroundColor Red
# Trigger your alert action here
}
$seenIds += $email.id
}
# Keep seen list from growing forever
if ($seenIds.Count -gt 500) {
$seenIds = $seenIds[-200..-1]
}
Start-Sleep -Seconds 15
}Windows toast notifications with BurntToast
The BurntToast module creates native Windows 10/11 toast notifications from PowerShell. Install it once, then pop a notification for every new email.
# Install BurntToast (one time)
Install-Module -Name BurntToast -Scope CurrentUser -Force# toast-monitor.ps1 -- Desktop notifications for new emails
Import-Module BurntToast
$seenIds = @()
while ($true) {
$emails = nylas email list --unread --json --limit 10 | ConvertFrom-Json
foreach ($email in $emails) {
if ($email.id -in $seenIds) { continue }
New-BurntToastNotification `
-Text "New email from $($email.from)", $email.subject `
-AppLogo $null
$seenIds += $email.id
}
Start-Sleep -Seconds 20
}Send alerts to Microsoft Teams
Post to a Teams channel when specific emails arrive. Create an incoming webhook in Teams, then use Invoke-RestMethod to send a message.
# teams-alert.ps1 -- Post new email alerts to a Teams channel
$teamsWebhookUrl = $env:TEAMS_WEBHOOK_URL
$seenIds = @()
function Send-TeamsAlert {
param(
[string]$Subject,
[string]$From,
[string]$Preview
)
$body = @{
type = "message"
attachments = @(
@{
contentType = "application/vnd.microsoft.card.adaptive"
content = @{
type = "AdaptiveCard"
version = "1.4"
body = @(
@{
type = "TextBlock"
text = "New Email Alert"
weight = "Bolder"
size = "Medium"
}
@{
type = "FactSet"
facts = @(
@{ title = "From"; value = $From }
@{ title = "Subject"; value = $Subject }
@{ title = "Preview"; value = $Preview }
)
}
)
}
}
)
} | ConvertTo-Json -Depth 10
Invoke-RestMethod -Uri $teamsWebhookUrl -Method Post `
-ContentType "application/json" -Body $body
}
while ($true) {
$emails = nylas email list --unread --json --limit 10 | ConvertFrom-Json
foreach ($email in $emails) {
if ($email.id -in $seenIds) { continue }
Send-TeamsAlert `
-Subject $email.subject `
-From $email.from `
-Preview ($email.snippet ?? "")
$seenIds += $email.id
}
Start-Sleep -Seconds 30
}Watch for OTP codes
Nylas CLI has a dedicated OTP extraction command. Use nylas otp watch to poll for incoming verification codes in real time, or nylas otp get to grab the latest one.
# Watch for OTP codes in real time (blocks until a code arrives)
nylas otp watch
# Watch with a custom polling interval (every 5 seconds)
nylas otp watch --interval 5
# Get the most recent OTP code (non-blocking)
nylas otp get
# Get just the code for use in scripts (no formatting)
$code = nylas otp get --raw
Write-Host "Verification code: $code"Combine OTP watching with automation -- for example, auto-fill a verification form:
# otp-auto.ps1 -- Extract OTP and copy to clipboard
$code = nylas otp get --raw
if ($code) {
Set-Clipboard -Value $code
New-BurntToastNotification `
-Text "OTP Code Captured", "Code $code copied to clipboard" `
-AppLogo $null
Write-Host "OTP code $code copied to clipboard" -ForegroundColor Green
} else {
Write-Host "No OTP code found" -ForegroundColor Yellow
}Monitor unread count
Track unread counts over time and alert when they spike. Useful for detecting email floods or monitoring shared mailboxes.
# unread-monitor.ps1 -- Track unread count and alert on spikes
$threshold = 20
$previousCount = 0
while ($true) {
$emails = nylas email list --unread --json --limit 100 | ConvertFrom-Json
$count = $emails.Count
$delta = $count - $previousCount
if ($delta -gt 0) {
Write-Host "$(Get-Date -Format 'HH:mm:ss') Unread: $count (+$delta)" `
-ForegroundColor Yellow
} else {
Write-Host "$(Get-Date -Format 'HH:mm:ss') Unread: $count" `
-ForegroundColor Gray
}
if ($count -ge $threshold -and $previousCount -lt $threshold) {
Write-Host "SPIKE: Unread count hit $count (threshold: $threshold)" `
-ForegroundColor Red
# Trigger your alert here
}
$previousCount = $count
Start-Sleep -Seconds 60
}Detect bounced emails
Monitor your inbox for bounce notifications. Bounced emails typically come from "mailer-daemon" or contain specific subject patterns.
# bounce-monitor.ps1 -- Detect bounced emails
$seenIds = @()
while ($true) {
$emails = nylas email list --unread --json --limit 30 | ConvertFrom-Json
foreach ($email in $emails) {
if ($email.id -in $seenIds) { continue }
$isBounce = $false
# Check sender patterns
if ($email.from -match "mailer-daemon|postmaster|mail-delivery") {
$isBounce = $true
}
# Check subject patterns
if ($email.subject -match "delivery.*fail|undeliverable|returned mail|bounced") {
$isBounce = $true
}
if ($isBounce) {
Write-Host "BOUNCE: $($email.subject)" -ForegroundColor Red
Write-Host " From: $($email.from)" -ForegroundColor DarkRed
# Read full message for details
$detail = nylas email read $email.id --json | ConvertFrom-Json
Write-Host " Body preview: $($detail.snippet)" -ForegroundColor DarkGray
}
$seenIds += $email.id
}
Start-Sleep -Seconds 60
}Run as a Windows Scheduled Task
For persistent monitoring, register your script as a Windows Scheduled Task that starts at logon.
# Register the monitor script as a scheduled task
$action = New-ScheduledTaskAction `
-Execute "pwsh.exe" `
-Argument "-WindowStyle Hidden -File C:\Scripts\toast-monitor.ps1"
$trigger = New-ScheduledTaskTrigger -AtLogOn
$settings = New-ScheduledTaskSettingsSet `
-AllowStartIfOnBatteries `
-DontStopIfGoingOnBatteries `
-ExecutionTimeLimit (New-TimeSpan -Hours 0)
Register-ScheduledTask `
-TaskName "NylasEmailMonitor" `
-Action $action `
-Trigger $trigger `
-Settings $settings `
-Description "Monitor inbox with Nylas CLI"Frequently asked questions
Can I monitor email with PowerShell on Windows?
Yes. Nylas CLI is a standalone Go binary that runs natively on Windows. You can call it from PowerShell scripts, parse its JSON output with ConvertFrom-Json, and build monitoring loops with Start-Sleep. No Python, Node.js, or WSL required.
How do I get desktop notifications for new emails in PowerShell?
Install the BurntToast PowerShell module with Install-Module -Name BurntToast. Then call New-BurntToastNotification with the email subject and sender parsed from Nylas CLI JSON output. This creates native Windows 10/11 toast notifications.
Can Nylas CLI watch for OTP verification codes?
Yes. Use nylas otp watch to poll for incoming OTP codes in real time. It monitors your inbox and extracts verification codes automatically. Use --interval to set polling frequency and --raw to get just the code for scripts.
How do I send alerts to Microsoft Teams from a PowerShell email monitor?
Use Invoke-RestMethod to POST a JSON payload to a Teams incoming webhook URL. Format the message as an Adaptive Card or simple text payload. The PowerShell script detects new emails via Nylas CLI, then sends the alert to Teams.
Next steps
- Test email in CI/CD with PowerShell -- use these monitoring patterns in GitHub Actions and Azure DevOps
- E2E email testing with Playwright -- browser-based email verification
- Send email from the terminal -- sending side of the equation
- Full command reference -- every flag and subcommand