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

如何使用Azure Powershell Runbooks查询Azure虚拟机SSL证书有效期

最优实现方案

整体逻辑为通过Azure Runbook内置托管身份自动完成订阅鉴权,枚举当前订阅下所有虚拟机后,针对Windows、Linux操作系统分别调用Azure原生运行命令接口拉取证书存储中的SSL证书信息,计算有效期后可直接输出或持久化存储,无需在虚拟机内提前预装任何代理。


前置准备
  • 给Runbook配置系统分配托管身份,为该身份分配包含虚拟机读取、虚拟机运行命令权限的自定义角色,权限按最小原则配置即可,无需分配订阅级别的高权限
  • 确保Runbook运行环境已导入Az.Compute、Az.Accounts官方PowerShell模块
  • 所有目标虚拟机需允许来自Azure平台的运行命令调用,无需开放公网端口

核心实现步骤

1. 完成Azure订阅鉴权

在Runbook开头执行以下代码完成自动登录,无需明文存储账号密钥:

# 使用系统托管身份登录Azure
Connect-AzAccount -Identity | Out-Null
# 切换到目标订阅,替换为你的订阅ID
Set-AzContext -SubscriptionId "xxxx-xxxx-xxxx-xxxx" | Out-Null

2. 枚举订阅下所有虚拟机

$allVms = Get-AzVM
$certResult = @()

3. 按系统类型拉取SSL证书有效期

Windows VM查询逻辑

调用PowerShell命令拉取本地计算机证书存储中用于服务器身份验证的SSL证书:

foreach ($vm in $allVms) {
    if ($vm.StorageProfile.OsDisk.OsType -eq "Windows") {
        $winCertCmd = @"
Get-ChildItem Cert:\LocalMachine\My | 
Where-Object { `$_.EnhancedKeyUsageList.FriendlyName -contains 'Server Authentication' } | 
Select-Object @{Name='VmName';Expression={'$($vm.Name)'}},Subject, Thumbprint, NotBefore, NotAfter, @{Name='DaysRemaining';Expression={( `$_.NotAfter - (Get-Date)).Days}} | 
ConvertTo-Json
"@
        try {
            $runResult = Invoke-AzVMRunCommand -ResourceGroupName $vm.ResourceGroupName -Name $vm.Name -CommandId 'RunPowerShellScript' -ScriptString $winCertCmd -ErrorAction Stop
            $certResult += $runResult.Value[0].Message | ConvertFrom-Json
        }
        catch {
            Write-Warning "虚拟机 $($vm.Name) 无法访问,跳过查询"
            continue
        }
    }

Linux VM查询逻辑

调用Shell命令扫描常用证书存储路径,通过openssl工具解析证书有效期:

else {
        $linuxCertCmd = @"
find /etc/ssl /etc/nginx /etc/httpd /usr/local/share/ca-certificates -name "*.crt" -o -name "*.pem" | xargs -I {} openssl x509 -in {} -noout -subject -enddate 2>/dev/null | 
awk '
/^subject=/ {sub(/^subject=.*CN=/, "", \$0); sub(/[\/,].*/, "", \$0); sub(/^ */, "", \$0); s=\$0}
/^notAfter=/ {dt=substr(\$0,10); cmd="date -d \""dt"\" +%s"; cmd | getline ts; close(cmd); now=systime(); days=int((ts-now)/86400); print "{\'VmName\':\'$($vm.Name)\',\'Subject\':\'"s"\',\'NotAfter\':\'"dt"\',\'DaysRemaining\':"days"}"}'
"@
        try {
            $runResult = Invoke-AzVMRunCommand -ResourceGroupName $vm.ResourceGroupName -Name $vm.Name -CommandId 'RunShellScript' -ScriptString $linuxCertCmd -ErrorAction Stop
            $certResult += $runResult.Value[0].Message | ConvertFrom-Json
        }
        catch {
            Write-Warning "虚拟机 $($vm.Name) 无法访问,跳过查询"
            continue
        }
    }
}

4. 结果处理

# 直接输出结果到Runbook日志
$certResult | Format-Table
# 可选:将结果导出为CSV存入Azure存储账号Blob,方便后续查看或对接告警

优化建议
  • 为Runbook配置定时触发计划,比如每周执行一次自动巡检
  • 新增有效期阈值判断,当DaysRemaining小于30时自动触发告警通知
  • Linux侧如果证书存放在自定义路径,只需修改find命令后的扫描路径即可适配

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 10:09:03