You need to enable JavaScript to run this app. 如何简化Azure PowerShell Runbook 收集KV过期secrets/certs并发送格式化邮件
优惠活动
大模型
产品
解决方案
定价
更多

如何简化Azure PowerShell Runbook 收集KV过期secrets/certs并发送格式化邮件

简化后的Key Vault过期资产巡检Runbook实现

核心优化方向

  • 彻底消除重复逻辑:原代码重复执行2次KV列表拉取、过期阈值计算,且Secret、证书的巡检判断逻辑90%重复,本次抽成统一处理流程
  • 修复原有逻辑bug:原代码中已过期的Secret/证书的分类标签错误标记为「NearExpiration」,本次修正为对应过期分类
  • 新增HTML格式化邮件能力:自动生成带样式的巡检结果表格,可直接作为邮件正文发送给干系人
  • 完全兼容原有调用方式:保留原Runbook的核心入参定义,不影响现有定时巡检任务的配置

简化后完整可运行代码

Param(
        [string]$SubscriptionID = "",
        [int]$DaysNearExpiration = 30,
        [string]$VaultName,
        [string]$MailSmtpServer = "",
        [int]$MailSmtpPort = 587,
        [string]$MailSender = "",
        [string[]]$MailRecipients = @(),
        [string]$MailSubject = "Key Vault 密钥/证书过期巡检通知"
)
 
# 订阅切换逻辑与原有逻辑保持一致
Get-AzureRmSubscription -SubscriptionId $SubscriptionID | Select-AzureRmSubscription

# 时间阈值计算仅执行一次,直接用DateTime对象比较(替代原字符串格式比较,更可靠)
$ThresholdDate = (Get-Date).AddDays($DaysNearExpiration)
$CurrentDate = Get-Date

# KV列表拉取仅执行一次
if ($VaultName) {
    $KeyVaults = Get-AzureRmKeyVault -VaultName $VaultName
}
else {
    $KeyVaults = Get-AzureRmKeyVault
}

$AllExpireAssets = @()

# 遍历所有KV完成Secret与证书巡检
foreach ($KeyVault in $KeyVaults) {
    # 巡检当前KV下所有Secret
    $SecretsArray = Get-AzureKeyVaultSecret -VaultName $KeyVault.VaultName -ErrorAction SilentlyContinue
    foreach ($secret in $SecretsArray) {
        if (-not $secret.Expires) { continue }
        # 状态判断
        if ($secret.Expires -lt $CurrentDate) {
            $status = "已过期"
            $category = "ExpiredSecret"
        }
        elseif ($secret.Expires -lt $ThresholdDate) {
            $status = "即将过期"
            $category = "SecretNearExpiration"
        }
        else { continue }
        # 加入结果集合
        $AllExpireAssets += [PSCustomObject]@{
            资产类型       = $category
            资产名称       = $secret.Name
            所属KeyVault   = $KeyVault.VaultName
            过期日期       = $secret.Expires.ToString("yyyy-MM-dd")
            资产状态       = $status
        }
    }

    # 巡检当前KV下所有证书
    $CertificatesArray = Get-AzureKeyVaultCertificate -VaultName $KeyVault.VaultName -ErrorAction SilentlyContinue
    foreach ($Certificate in $CertificatesArray) {
        if (-not $Certificate.Expires) { continue }
        if ($Certificate.Expires -lt $CurrentDate) {
            $status = "已过期"
            $category = "ExpiredCertificate"
        }
        elseif ($Certificate.Expires -lt $ThresholdDate) {
            $status = "即将过期"
            $category = "CertificateNearExpiration"
        }
        else { continue }
        $AllExpireAssets += [PSCustomObject]@{
            资产类型       = $category
            资产名称       = $Certificate.Name
            所属KeyVault   = $KeyVault.VaultName
            过期日期       = $Certificate.Expires.ToString("yyyy-MM-dd")
            资产状态       = $status
        }
    }
}

# 控制台输出,供Runbook运行日志查看
Write-Output "巡检完成,共发现需关注的过期/即将过期资产 $($AllExpireAssets.Count) 项"
$AllExpireAssets | Format-Table -AutoSize

# 生成HTML格式邮件正文
if ($AllExpireAssets.Count -eq 0) {
    $htmlBody = "<h3>巡检完成:近 $DaysNearExpiration 天内无即将过期/已过期的密钥或证书</h3>"
}
else {
    # 按状态排序,已过期资产置顶
    $sortedAssets = $AllExpireAssets | Sort-Object @{Expression="资产状态";Descending=$true}, 过期日期
    # 生成基础HTML表格并增加邮件友好的样式
    $htmlTable = $sortedAssets | ConvertTo-Html -Fragment -PreContent "<h4>需关注资产明细:</h4>"
    $htmlBody = @"
    <style>
        table { border-collapse: collapse; width: 90%; margin: 20px 0; }
        th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
        th { background-color: #f5f5f5; }
        tr:nth-child(even) { background-color: #f9f9f9; }
    </style>
    $htmlTable
"@
}

# 邮件发送逻辑:仅当配置了完整SMTP参数时触发
if ($MailSmtpServer -and $MailSender -and $MailRecipients.Count -gt 0) {
    Send-MailMessage -SmtpServer $MailSmtpServer -Port $MailSmtpPort -From $MailSender -To $MailRecipients -Subject $MailSubject -Body $htmlBody -BodyAsHtml -UseSsl
}

额外说明

  • 本次优化将原代码近400行的重复逻辑压缩至150行左右,减少了2次冗余的KV列表拉取API调用
  • 增加了-ErrorAction SilentlyContinue参数,避免单个Key Vault无访问权限时中断整个巡检流程
  • 邮件入参为可选配置,不配置SMTP信息时,Runbook会正常输出控制台巡检结果,完全兼容原有使用习惯
  • 可直接在Azure自动化账户中配置该Runbook的定时触发计划,定期执行并自动推送巡检结果

内容的提问来源于stack exchange,提问作者Taylor83

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.05 17:15:04