多订阅Key Vault过期密钥、机密、证书查询脚本Runbook执行报错求助
Azure自动化Runbook执行密钥过期检查脚本报错问题
问题说明
需运行PowerShell脚本从多Azure订阅的多Key Vault中筛选已过期/未来20天内即将过期的密钥、机密、证书,期望输出包含订阅名称、Key Vault名称、对象类别、对象名称、过期日期、剩余天数的表格,但在Azure Automation Account Runbook中执行时出错。
当前使用的脚本
Connect-AzAccount -Identity $AlertBeforeDays = 20 # 从Key Vault获取即将过期项目的函数 function Get-ExpiringItems { param ( [string]$VaultName, [datetime]$ExpiryDate ) $ExpiringItems = @() # 检查已过期/即将过期的密钥 $Keys = Get-AzKeyVaultKey -VaultName $VaultName $ExpiringKeys = $Keys | Where-Object { $_.Attributes.Expires -lt $ExpiryDate } $ExpiringKeys | ForEach-Object { $ExpiringItems += [PSCustomObject]@{ VaultName = $VaultName ItemType = "Key" ItemName = $_.Key.Kid ExpiryDate = $_.Attributes.Expires } } # 检查已过期/即将过期的机密 $Secrets = Get-AzKeyVaultSecret -VaultName $VaultName $ExpiringSecrets = $Secrets | Where-Object { $_.Attributes.Expires -lt $ExpiryDate } $ExpiringSecrets | ForEach-Object { $ExpiringItems += [PSCustomObject]@{ VaultName = $VaultName ItemType = "Secret" ItemName = $_.Id ExpiryDate = $_.Attributes.Expires } } # 检查已过期/即将过期的证书 $Certificates = Get-AzKeyVaultCertificate -VaultName $VaultName $ExpiringCertificates = $Certificates | Where-Object { $_.Attributes.Expires -lt $ExpiryDate } $ExpiringCertificates | ForEach-Object { $ExpiringItems += [PSCustomObject]@{ VaultName = $VaultName ItemType = "Certificate" ItemName = $_.Id ExpiryDate = $_.Attributes.Expires } } return $ExpiringItems } # 获取当前日期及20天后的日期 $CurrentDate = Get-Date $ExpiryDate = $CurrentDate.AddDays($AlertBeforeDays) # 初始化存储所有即将过期项目的数组 $AllExpiringItems = @() # 获取所有订阅 $Subscriptions = Get-AzSubscription # 遍历每个订阅 foreach ($Subscription in $Subscriptions) { Set-AzContext -SubscriptionId $Subscription.Id # 获取订阅内所有Key Vault $KeyVaults = Get-AzKeyVault # 遍历每个Key Vault foreach ($KeyVault in $KeyVaults) { $VaultName = $KeyVault.VaultName $ExpiringItems = Get-ExpiringItems -VaultName $VaultName -ExpiryDate $ExpiryDate $AllExpiringItems += $ExpiringItems } } # 表格格式输出结果 $AllExpiringItems | Format-Table -Property VaultName, ItemType, ItemName, ExpiryDate -AutoSize
常见报错原因及修复方案
1. Az模块缺失/版本不兼容
- 问题:自动化账户未安装
Az.Accounts、Az.KeyVault等必需模块,或版本过低导致cmdlet无法运行。 - 修复:
- 进入自动化账户模块页面,检查
Az.Accounts和Az.KeyVault是否存在; - 缺失则从模块库导入,版本过低则更新至兼容的最新版本。
- 进入自动化账户模块页面,检查
2. 托管标识权限不足
- 问题:Runbook使用的托管标识无足够权限访问订阅和Key Vault资源。
- 修复:
- 为托管标识分配订阅级别的
Reader角色,用于遍历订阅和Key Vault; - 为托管标识分配目标Key Vault的
Key Vault Reader或Key Vault Secrets User等角色,确保能读取密钥、机密、证书的属性。
- 为托管标识分配订阅级别的
3. 脚本逻辑缺陷
原脚本未满足输出需求(缺少订阅名称、剩余天数),且未处理无过期日期的资源,同时可能因输出格式导致Runbook显示异常。以下是修复后的脚本:
Connect-AzAccount -Identity $AlertBeforeDays = 20 # 从Key Vault获取即将过期项目的函数 function Get-ExpiringItems { param ( [string]$VaultName, [datetime]$ExpiryDate, [string]$SubscriptionName ) $ExpiringItems = @() # 处理密钥 $Keys = Get-AzKeyVaultKey -VaultName $VaultName $ExpiringKeys = $Keys | Where-Object { $_.Attributes.Expires -ne $null -and $_.Attributes.Expires -lt $ExpiryDate } $ExpiringKeys | ForEach-Object { $remainingDays = ($_.Attributes.Expires - (Get-Date)).Days $ExpiringItems += [PSCustomObject]@{ 订阅名称 = $SubscriptionName KeyVault名称 = $VaultName 对象类别 = "密钥" 对象名称 = ($_.Key.Kid -split '/')[-1] 过期日期 = $_.Attributes.Expires 剩余天数 = $remainingDays } } # 处理机密 $Secrets = Get-AzKeyVaultSecret -VaultName $VaultName $ExpiringSecrets = $Secrets | Where-Object { $_.Attributes.Expires -ne $null -and $_.Attributes.Expires -lt $ExpiryDate } $ExpiringSecrets | ForEach-Object { $remainingDays = ($_.Attributes.Expires - (Get-Date)).Days $ExpiringItems += [PSCustomObject]@{ 订阅名称 = $SubscriptionName KeyVault名称 = $VaultName 对象类别 = "机密" 对象名称 = ($_.Id -split '/')[-1] 过期日期 = $_.Attributes.Expires 剩余天数 = $remainingDays } } # 处理证书 $Certificates = Get-AzKeyVaultCertificate -VaultName $VaultName $ExpiringCertificates = $Certificates | Where-Object { $_.Attributes.Expires -ne $null -and $_.Attributes.Expires -lt $ExpiryDate } $ExpiringCertificates | ForEach-Object { $remainingDays = ($_.Attributes.Expires - (Get-Date)).Days $ExpiringItems += [PSCustomObject]@{ 订阅名称 = $SubscriptionName KeyVault名称 = $VaultName 对象类别 = "证书" 对象名称 = ($_.Id -split '/')[-1] 过期日期 = $_.Attributes.Expires 剩余天数 = $remainingDays } } return $ExpiringItems } # 计算阈值日期 $CurrentDate = Get-Date $ExpiryDate = $CurrentDate.AddDays($AlertBeforeDays) $AllExpiringItems = @() # 遍历所有订阅 $Subscriptions = Get-AzSubscription foreach ($Subscription in $Subscriptions) { $null = Set-AzContext -SubscriptionId $Subscription.Id $subscriptionName = $Subscription.Name # 遍历当前订阅下的Key Vault $KeyVaults = Get-AzKeyVault foreach ($KeyVault in $KeyVaults) { $ExpiringItems = Get-ExpiringItems -VaultName $KeyVault.VaultName -ExpiryDate $ExpiryDate -SubscriptionName $subscriptionName $AllExpiringItems += $ExpiringItems } } # 输出符合需求的表格 $AllExpiringItems | Select-Object 订阅名称, KeyVault名称, 对象类别, 对象名称, 过期日期, 剩余天数 | Format-Table -AutoSize
- 修复要点:
- 添加订阅名称和剩余天数字段,匹配输出需求;
- 跳过无过期日期的资源,避免空值报错;
- 提取对象短名称(而非完整ID),提升可读性;
- 使用
$null = Set-AzContext屏蔽冗余输出。
4. Runbook执行限制
- 问题:订阅/Key Vault数量过多时,脚本执行超时或因并发限制中断。
- 修复:
- 改用并行处理(如
ForEach-Object -Parallel)提升效率; - 在自动化账户中调整Runbook的执行超时时间。
- 改用并行处理(如
内容的提问来源于stack exchange,提问作者Manju S
相关产品推荐
相关产品推荐

