0

PowerShell 邮件告警自动化脚本:5个实战场景让服务器监控不再漏报

2026.05.31 | youres | 1次围观

目录

  • 为什么需要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 任务计划程序是最佳选择,无需第三方守护进程。

配置步骤:

  1. 打开「任务计划程序」→ 创建基本任务
  2. 触发器:设为「启动时」或「每隔X分钟」
  3. 操作:启动程序 → 程序/脚本填 powershell.exe
  4. 参数:-File "C:\Scripts\ServiceMonitor.ps1" -ExecutionPolicy Bypass
  5. 勾选「使用最高权限运行」,避免权限不足导致脚本执行失败

如果想更精细地控制,可以用 Register-ScheduledTask 命令行创建,便于批量部署到多台服务器。

总结与最佳实践

PowerShell 邮件告警自动化脚本的核心价值在于:把"人为发现故障"变成"系统主动通知",大幅缩短故障响应时间。实际落地时有几个建议:

  • 告警分级:-Priority High 标记紧急告警,普通巡检用 Normal,避免邮件轰炸
  • 避免重复告警:发邮件前先写个标记文件,同一问题30分钟内不重复发信
  • SMTP 凭证加密存储:不要把邮箱密码明文写在脚本里,用 ConvertTo-SecureString 加密后保存
  • 多通道告警:邮件 + 钉钉机器人 双通道,确保告警不漏接(可以参考 PowerShell 安全响应头自动化巡检方案 里的告警通知思路)

邮件告警只是自动化运维的第一步。当你把这些脚本和 CI/CD、监控平台打通,整个基础设施会真正"活"起来。

相关阅读:
PowerShell 安全响应头自动化巡检方案
curl 查看 HTTP 响应头所有字段
Nginx HSTS max-age 设置建议

版权声明

本文仅代表个人观点。
本文系AI辅助作者原创,未经许可,转载请保留原文链接。

发表评论