You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:01:04