目录
- 为什么需要PowerShell邮件告警脚本
- 方案一:Send-MailMessage(原生,最简单)
- 方案二:MailKit(推荐,支持现代认证)
- 实战场景一:Windows服务状态监控告警
- 实战场景二:磁盘空间不足自动邮件告警
- 实战场景三:安全日志事件触发邮件通知
- 实战场景四:HTTPS证书到期邮件提醒
- 实战场景五:定时巡检报告自动发送
- 任务计划程序配置:让脚本自动运行
- 总结与最佳实践
为什么需要PowerShell邮件告警脚本
服务器半夜挂了,网站访问异常,结果早上才知道——这是每个运维人都经历过的噩梦。与其被动等用户投诉,不如主动让服务器自己"喊救命"。
PowerShell 邮件告警自动化脚本就是干这件事的:监控指标超阈值 → 自动触发 → 发邮件通知你。整个链路无需人工干预,真正做到"枕戈待旦"。
方案一:Send-MailMessage(原生,最简单)
PowerShell 内置 Send-MailMessage,无需安装任何模块,适合内网 SMTP 服务器或企业邮箱。
# 最基础的发信示例
$subject = "服务器告警:CPU使用率超过90%"
$body = @"
告警时间:$(Get-Date)
服务器名:$env:COMPUTERNAME
CPU使用率:92%
处理建议:请立即登录检查
"@
Send-MailMessage `
-SmtpServer "smtp.yourcompany.com" `
-Port 25 `
-From "monitor@yourcompany.com" `
-To "admin@yourcompany.com" `
-Subject $subject `
-Body $body `
-Priority High
注意:Send-MailMessage 不支持现代 OAuth2 认证,如果你用的是 Gmail、Outlook 等公共邮箱,需要用方案二(MailKit)。微软官方也已将其标记为"不推荐",但在内网环境仍然好用。
方案二:MailKit(推荐,支持现代认证)
MailKit 是 .NET 下最流行的邮件库,支持 OAuth2、TLS、附件,适合对接 Gmail、QQ邮箱、企业微信邮件等。
# 先安装 MailKit(只需一次)
Install-Package MailKit -Scope CurrentUser
# 使用 MailKit 发送告警邮件
Import-Module PackageManagement
Add-Type -Path "$env:USERPROFILE\.nuget\packages\mailkit\*\lib\net6.0\MailKit.dll"
$smtp = New-Object MailKit.Net.Smtp.SmtpClient
$smtp.Connect("smtp.gmail.com", 587, [MailKit.Security.SecureSocketOptions]::StartTls)
$smtp.Authenticate("your@gmail.com", "app_password")
$message = New-Object MimeKit.MimeMessage
$message.From.Add([MimeKit.MailboxAddress]::Parse("告警系统 <your@gmail.com>"))
$message.To.Add([MimeKit.MailboxAddress]::Parse("admin@yourcompany.com"))
$message.Subject = "服务器告警:磁盘空间不足"
$message.Body = [MimeKit.TextPart]::new("plain")
$message.Body.Text = "服务器 $env:COMPUTERNAME 磁盘 C: 剩余空间低于 10GB,请及时处理。"
$smtp.Send($message)
$smtp.Disconnect($true)
如果你用的是 QQ 邮箱或 163 邮箱,密码栏填的是授权码,不是登录密码,这个坑很多人踩过。
实战场景一:Windows服务状态监控告警
关键服务(如 IIS、MySQL、Redis)停止后,必须在第一时间感知。以下脚本每5分钟检查一次,服务停止立即发邮件。
$services = @("W3SVC", "MSSQLSERVER", "Redis")
$down = @()
foreach ($svc in $services) {
$status = Get-Service -Name $svc -ErrorAction SilentlyContinue
if ($status.Status -ne "Running") {
$down += "$svc 当前状态:$($status.Status)"
}
}
if ($down.Count -gt 0) {
$body = "以下服务异常停止:`n" + ($down -join "`n")
Send-MailMessage -SmtpServer "smtp.xxx.com" -From "monitor@xxx.com" `
-To "admin@xxx.com" -Subject "告警:服务异常停止" -Body $body -Priority High
}
将此脚本保存为 ServiceMonitor.ps1,通过任务计划程序设置每5分钟触发一次,就能实现持续监控。
实战场景二:磁盘空间不足自动邮件告警
磁盘写满导致数据库崩溃,是运维事故里的"常客"。提前设置阈值,空间不足自动发邮件,把事故消灭在萌芽状态。
$thresholdGB = 10
$drives = Get-PSDrive -PSProvider FileSystem
foreach ($drive in $drives) {
if ($drive.Free -lt ($thresholdGB * 1GB)) {
$freeGB = [math]::Round($drive.Free / 1GB, 2)
$body = "磁盘 $($drive.Name): 剩余空间仅 ${freeGB}GB,低于告警阈值 ${thresholdGB}GB"
# 调用发信函数(见方案一)
Send-MailMessage -SmtpServer "smtp.xxx.com" -From "monitor@xxx.com" `
-To "admin@xxx.com" -Subject "磁盘空间告警" -Body $body -Priority High
}
}
实战场景三:安全日志事件触发邮件通知
Windows 安全日志里记录了登录失败、权限变更等关键事件。通过 PowerShell 订阅事件,发生异常立即推送邮件,比任何第三方工具都快。
# 监控登录失败事件(EventID 4625)
$events = Get-WinEvent -FilterHashtable @{LogName='Security'; ID=4625; StartTime=(Get-Date).AddMinutes(-10)} -ErrorAction SilentlyContinue
if ($events.Count -ge 5) {
$body = "服务器 $env:COMPUTERNAME 在最近10分钟内检测到 $($events.Count) 次登录失败,疑似暴力破解攻击!"
Send-MailMessage -SmtpServer "smtp.xxx.com" -From "monitor@xxx.com" `
-To "admin@xxx.com" -Subject "安全告警:疑似暴力破解攻击" -Body $body -Priority High
}
实战场景四:HTTPS证书到期邮件提醒
证书过期导致网站无法访问,这类事故本可以完全避免。用 PowerShell 定期检查证书有效期,提前30天发邮件提醒,彻底告别证书过期焦虑。
$domain = "www.youres.cn"
$cert = echo | openssl s_client -servername $domain -connect "${domain}:443" 2>$null | openssl x509 -noout -dates 2>$null
$notAfter = [datetime]($cert -split "=")[1]
$daysLeft = ($notAfter - (Get-Date)).Days
if ($daysLeft -lt 30) {
$body = "域名 ${domain} 的HTTPS证书还有 ${daysLeft} 天到期(到期时间:${notAfter}),请尽快续签!"
Send-MailMessage -SmtpServer "smtp.xxx.com" -From "monitor@xxx.com" `
-To "admin@xxx.com" -Subject "证书到期预警" -Body $body -Priority High
}
这个脚本也可以扩展为批量检查多个域名,配合循环遍历域名列表即可,思路完全一样。
实战场景五:定时巡检报告自动发送
每天早上收到一份服务器健康报告,比咖啡还提神。把 CPU、内存、磁盘、服务状态打包成 HTML 报告,定时发送到邮箱。
$report = @"
<h2>服务器巡检报告 - $(Get-Date -Format 'yyyy-MM-dd')</h2>
<p>CPU使用率:$(Get-Counter '\Processor(_Total)\% Processor Time').CounterSamples.CookedValue -as [int])%</p>
<p>可用内存:$([math]::Round((Get-CimInstance Win32_OperatingSystem).FreePhysicalMemory / 1MB, 2)) GB</p>
<p>磁盘状态:$(Get-PSDrive -PSProvider FileSystem | Select-Object Name,Used,Free | ConvertTo-Html -Fragment)</p>
"@
Send-MailMessage -SmtpServer "smtp.xxx.com" -From "monitor@xxx.com" `
-To "admin@xxx.com" -Subject "每日巡检报告" -Body $report -BodyAsHtml
任务计划程序配置:让脚本自动运行
脚本写好了,还需要让它在后台持续运行。Windows 任务计划程序是最佳选择,无需第三方守护进程。
配置步骤:
- 打开「任务计划程序」→ 创建基本任务
- 触发器:设为「启动时」或「每隔X分钟」
- 操作:启动程序 → 程序/脚本填
powershell.exe - 参数:
-File "C:\Scripts\ServiceMonitor.ps1" -ExecutionPolicy Bypass - 勾选「使用最高权限运行」,避免权限不足导致脚本执行失败
如果想更精细地控制,可以用 Register-ScheduledTask 命令行创建,便于批量部署到多台服务器。
总结与最佳实践
PowerShell 邮件告警自动化脚本的核心价值在于:把"人为发现故障"变成"系统主动通知",大幅缩短故障响应时间。实际落地时有几个建议:
- 告警分级:用
-Priority High标记紧急告警,普通巡检用 Normal,避免邮件轰炸 - 避免重复告警:发邮件前先写个标记文件,同一问题30分钟内不重复发信
- SMTP 凭证加密存储:不要把邮箱密码明文写在脚本里,用
ConvertTo-SecureString加密后保存 - 多通道告警:邮件 + 钉钉机器人 双通道,确保告警不漏接(可以参考 PowerShell 安全响应头自动化巡检方案 里的告警通知思路)
邮件告警只是自动化运维的第一步。当你把这些脚本和 CI/CD、监控平台打通,整个基础设施会真正"活"起来。
相关阅读:
PowerShell 安全响应头自动化巡检方案
curl 查看 HTTP 响应头所有字段
Nginx HSTS max-age 设置建议
版权声明
本文仅代表个人观点。
本文系AI辅助作者原创,未经许可,转载请保留原文链接。

发表评论