如何用PowerShell获取证书剩余有效期并实现30天到期邮件告警
没问题,我来帮你一步步实现证书到期监控和邮件告警的需求,结合你已经有的证书定位命令,咱们来完善整个流程:
完整解决方案拆解
1. 先搞定证书剩余有效期计算
你已经能定位到目标证书了,接下来只要从证书对象里提取到期时间,再和当前日期做差值计算就能得到剩余天数。直接在你现有代码基础上扩展就行:
# 定义目标证书指纹 $certThumbprint = "AAAAAAAEEEEEEEFIIIIIIIIIOOOOOOOOUUUUUUUU" # 定位证书对象 $cert = Get-ChildItem -Path cert: -Recurse | Where-Object {$_.Thumbprint -eq $certThumbprint} # 计算剩余有效期天数 $currentDate = Get-Date $daysRemaining = ($cert.NotAfter - $currentDate).Days
这里$cert.NotAfter是证书的到期时间属性,和当前日期Get-Date做减法后,.Days属性就能直接拿到剩余的整数天数。
2. 判断是否需要触发告警
根据你的需求,只要剩余天数≤30天(包括已经过期但还没续期的情况),就需要发送通知。咱们用简单的条件判断来实现:
# 判断是否进入告警区间 $needsAlert = $daysRemaining -le 30
如果需要排除已经过期超过N天的情况(比如过期超过7天就不再通知),可以改成:
$needsAlert = $daysRemaining -le 30 -and $daysRemaining -ge -7
3. 配置邮件通知
接下来用PowerShell自带的Send-MailMessage命令发送告警邮件,你需要替换成自己的SMTP服务器和邮箱信息:
if ($needsAlert) { # 邮件基础配置 $smtpServer = "smtp.yourcompany.com" # 替换成你的SMTP服务器地址 $from = "cert-monitor@yourcompany.com" $to = "admin-team@yourcompany.com" $subject = "⚠️ 紧急:证书即将到期,请及时续期" # 邮件内容(支持HTML格式,排版更清晰) $body = @" <h3>证书到期告警通知</h3> <p>以下证书的剩余有效期已不足30天,请尽快处理续期:</p> <ul> <li>证书指纹:$certThumbprint</li> <li>证书主题:$cert.Subject</li> <li>剩余天数:$daysRemaining 天</li> <li>到期时间:$($cert.NotAfter.ToString('yyyy-MM-dd HH:mm:ss'))</li> </ul> "@ # 发送邮件 Send-MailMessage -SmtpServer $smtpServer -From $from -To $to -Subject $subject -Body $body -BodyAsHtml }
注意:如果是PowerShell 7及以上版本,
Send-MailMessage被标记为弃用,推荐使用Send-MailKitMessage模块,你可以用Install-Module -Name Send-MailKitMessage安装后替换命令逻辑,参数用法类似。
4. 自动化持续监控
手动跑脚本肯定不现实,咱们把脚本做成Windows计划任务,让它每天自动执行一次:
- 把上面的完整代码保存为
CertExpiryMonitor.ps1文件 - 打开「任务计划程序」,创建新任务:
- 触发器:选择「每天」,设置一个合适的执行时间(比如早上9点)
- 操作:选择「启动程序」,程序填
powershell.exe,参数填-ExecutionPolicy Bypass -File "C:\路径\到\你的脚本\CertExpiryMonitor.ps1" - 设置:勾选「不管用户是否登录都要运行」,确保脚本能稳定执行
5. 续期完成后自动停止告警
为了避免续期后还一直收到通知,咱们可以加个小逻辑:记录证书的到期时间,当发现到期时间更新了(说明续期完成),就停止发送邮件:
# 用来记录上次到期时间的文件路径(自己找个合适的目录) $lastExpiryRecord = "C:\CertMonitor\LastExpiryDate.txt" # 检查是否有历史记录 if (Test-Path $lastExpiryRecord) { $lastExpiryDate = Get-Content $lastExpiryRecord | Get-Date # 如果当前证书到期时间晚于历史记录,说明已续期 if ($cert.NotAfter -gt $lastExpiryDate) { Write-Host "证书已完成续期,本次不发送通知" # 更新历史记录为新的到期时间 $cert.NotAfter.ToString('yyyy-MM-dd HH:mm:ss') | Set-Content $lastExpiryRecord exit # 直接退出脚本 } } else { # 首次运行,创建记录文件 New-Item -Path (Split-Path $lastExpiryRecord) -ItemType Directory -Force | Out-Null $cert.NotAfter.ToString('yyyy-MM-dd HH:mm:ss') | Set-Content $lastExpiryRecord } # 下面再执行之前的天数计算、告警判断和邮件发送逻辑...
完整脚本示例
把所有部分整合起来,就是一个完整的监控脚本:
# -------------------------- # 证书到期监控告警脚本 # -------------------------- # 配置参数 $certThumbprint = "AAAAAAAEEEEEEEFIIIIIIIIIOOOOOOOOUUUUUUUU" $smtpServer = "smtp.yourcompany.com" $fromAddress = "cert-monitor@yourcompany.com" $toAddress = "admin-team@yourcompany.com" $lastExpiryRecord = "C:\CertMonitor\LastExpiryDate.txt" # 1. 定位目标证书 try { $cert = Get-ChildItem -Path cert: -Recurse | Where-Object {$_.Thumbprint -eq $certThumbprint} -ErrorAction Stop if (-not $cert) { throw "未找到指纹为 $certThumbprint 的证书" } } catch { Write-Error "证书定位失败:$_" exit 1 } # 2. 检查是否已续期 if (Test-Path $lastExpiryRecord) { $lastExpiryDate = Get-Content $lastExpiryRecord | Get-Date if ($cert.NotAfter -gt $lastExpiryDate) { Write-Host "证书已续期,到期时间更新为:$($cert.NotAfter.ToString('yyyy-MM-dd HH:mm:ss'))" $cert.NotAfter.ToString('yyyy-MM-dd HH:mm:ss') | Set-Content $lastExpiryRecord exit 0 } } else { New-Item -Path (Split-Path $lastExpiryRecord) -ItemType Directory -Force | Out-Null $cert.NotAfter.ToString('yyyy-MM-dd HH:mm:ss') | Set-Content $lastExpiryRecord } # 3. 计算剩余天数 $currentDate = Get-Date $daysRemaining = ($cert.NotAfter - $currentDate).Days # 4. 判断是否需要告警 if ($daysRemaining -le 30) { # 构造邮件内容 $subject = if ($daysRemaining -gt 0) { "⚠️ 证书即将到期:剩余 $daysRemaining 天" } else { "❌ 证书已过期:已过期 $(-$daysRemaining) 天" } $body = @" <h3>证书到期告警</h3> <p>请关注以下证书的续期进度:</p> <ul> <li>证书指纹:$certThumbprint</li> <li>证书主题:$cert.Subject</li> <li>剩余/已过期天数:$daysRemaining 天</li> <li>到期时间:$($cert.NotAfter.ToString('yyyy-MM-dd HH:mm:ss'))</li> </ul> "@ # 发送邮件 try { Send-MailMessage -SmtpServer $smtpServer -From $fromAddress -To $toAddress -Subject $subject -Body $body -BodyAsHtml -ErrorAction Stop Write-Host "告警邮件已成功发送" } catch { Write-Error "邮件发送失败:$_" exit 1 } } else { Write-Host "证书剩余有效期充足:$daysRemaining 天,无需告警" }
内容的提问来源于stack exchange,提问作者elmizu
相关产品推荐
相关产品推荐

