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

配置PowerShell Runbook定期推送密钥库过期项邮件通知

实现Azure自动化Runbook定期推送KeyVault过期资产邮件指南

一、修改Runbook脚本,添加邮件发送逻辑

你的现有脚本已能筛选7天内到期的资产,但未覆盖已过期的资产(原条件$remainingDays -le 7 -and $remainingDays -ge 0会排除剩余天数为负的已过期项),同时需要补充邮件发送功能。以下是修改后的完整脚本:

$expirationDetails = @()

# 提前定义工具函数,避免循环内重复定义
function Check-Expiration($expiryDate) {
    if ($expiryDate) {
        return [datetime]$expiryDate
    }
    return $null
}

function Get-RemainingDays($expiryDate) {
    if ($expiryDate -ne $null) {
        $remainingDays = ($expiryDate - (Get-Date)).Days
        return $remainingDays
    }
    return $null
}

# 遍历所有订阅
$subscriptions = Get-AzSubscription
foreach ($subscription in $subscriptions) {
    Set-AzContext -SubscriptionId $subscription.Id | Out-Null
    $kvnames = Get-AzKeyVault

    foreach ($kvitem in $kvnames) {
        $secrets = Get-AzKeyVaultSecret -VaultName $kvitem.VaultName
        $keys = Get-AzKeyVaultKey -VaultName $kvitem.VaultName
        $certificates = Get-AzKeyVaultCertificate -VaultName $kvitem.VaultName

        # 处理机密
        foreach ($secret in $secrets) {
            $expirationDate = Check-Expiration $secret.Expires
            $remainingDays = Get-RemainingDays $expirationDate

            $formattedExpirationDate = if ($expirationDate) { $expirationDate.ToString("MM/dd/yyyy HH:mm:ss") } else { "" }

            # 筛选已过期(<=0)和7天内即将过期的资产
            if ($remainingDays -le 7 -and $remainingDays -ne $null) {
                $expirationDetails += [PSCustomObject]@{
                    SubscriptionName  = $subscription.Name
                    ResourceGroupName = $kvitem.ResourceGroupName
                    ResourceName      = $kvitem.VaultName
                    ObjectName        = $secret.Name
                    ObjectCategory    = "Secret"
                    ExpirationDate    = $formattedExpirationDate
                    ExpiresIn         = if ($remainingDays -lt 0) { "已过期" } else { "$remainingDays 天" }
                }
            }
        }

        # 处理密钥
        foreach ($key in $keys) {
            $expirationDate = Check-Expiration $key.Attributes.Expires
            $remainingDays = Get-RemainingDays $expirationDate

            $formattedExpirationDate = if ($expirationDate) { $expirationDate.ToString("MM/dd/yyyy HH:mm:ss") } else { "" }

            if ($remainingDays -le 7 -and $remainingDays -ne $null) {
                $expirationDetails += [PSCustomObject]@{
                    SubscriptionName  = $subscription.Name
                    ResourceGroupName = $kvitem.ResourceGroupName
                    ResourceName      = $kvitem.VaultName
                    ObjectName        = $key.Name
                    ObjectCategory    = "Key"
                    ExpirationDate    = $formattedExpirationDate
                    ExpiresIn         = if ($remainingDays -lt 0) { "已过期" } else { "$remainingDays 天" }
                }
            }
        }

        # 处理证书
        foreach ($certificate in $certificates) {
            $expirationDate = Check-Expiration $certificate.Attributes.Expires
            $remainingDays = Get-RemainingDays $expirationDate

            $formattedExpirationDate = if ($expirationDate) { $expirationDate.ToString("MM/dd/yyyy HH:mm:ss") } else { "" }

            if ($remainingDays -le 7 -and $remainingDays -ne $null) {
                $expirationDetails += [PSCustomObject]@{
                    SubscriptionName  = $subscription.Name
                    ResourceGroupName = $kvitem.ResourceGroupName
                    ResourceName      = $kvitem.VaultName
                    ObjectName        = $certificate.Name
                    ObjectCategory    = "Certificate"
                    ExpirationDate    = $formattedExpirationDate
                    ExpiresIn         = if ($remainingDays -lt 0) { "已过期" } else { "$remainingDays 天" }
                }
            }
        }
    }
}

# 准备邮件内容
$emailSubject = "KeyVault资产过期提醒 - $(Get-Date -Format 'yyyy-MM-dd')"
$emailTo = "你的收件邮箱@domain.com"
$emailFrom = "发件邮箱@domain.com"

# 生成HTML格式邮件体,优化显示效果
if ($expirationDetails.Count -gt 0) {
    $htmlBody = @"
    <html>
    <head>
        <style>
            table { border-collapse: collapse; width: 100%; margin: 10px 0; }
            th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
            th { background-color: #f2f2f2; }
            .expired { color: #dc3545; font-weight: bold; }
        </style>
    </head>
    <body>
        <h3>以下KeyVault资产已过期或将于7天内过期:</h3>
        $(($expirationDetails | ConvertTo-Html -Fragment) -replace '<td>已过期</td>', '<td class="expired">已过期</td>')
    </body>
    </html>
"@
} else {
    $htmlBody = "<html><body><h3>当前无已过期或7天内即将过期的KeyVault资产。</h3></body></html>"
}

# 发送邮件(以SMTP为例,若用Azure SendGrid可替换为对应逻辑)
# 注意:敏感信息如SMTP密码建议存入KeyVault,通过Get-AzKeyVaultSecret获取
$smtpServer = "smtp.domain.com"
$smtpPort = 587
$smtpCredential = New-Object System.Net.NetworkCredential("smtp用户名", "smtp密码")

Send-MailMessage -From $emailFrom -To $emailTo -Subject $emailSubject -Body $htmlBody -BodyAsHtml -SmtpServer $smtpServer -Port $smtpPort -UseSsl -Credential $smtpCredential

脚本关键调整:

  • 修正筛选逻辑,包含已过期和7天内到期的资产
  • 将工具函数移至循环外,避免重复定义导致的性能问题
  • 优化剩余天数显示,用“已过期”替代负数,更直观
  • 生成带样式的HTML邮件,提升可读性
  • 支持无过期资产时发送提示邮件

二、配置自动化账户依赖资源

  1. 存储敏感信息:将SMTP密码或SendGrid API密钥存入KeyVault,避免硬编码。给自动化账户的RunAs账户分配KeyVault的Get Secret权限。
  2. 验证模块:确保自动化账户已安装Az.KeyVault模块,若缺失可在“模块”页面导入官方模块。

三、设置Runbook定期触发计划

  1. 登录Azure门户,进入目标自动化账户
  2. 左侧菜单选择“Runbook”,找到已修改的Runbook
  3. 点击“链接到计划”,选择“创建新计划”
  4. 设置计划类型为每日,指定执行时间(如凌晨2点),保存计划
  5. 确认Runbook已关联该计划,后续将按设定时间自动执行并发送邮件

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 12:09:51