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

多订阅场景下如何通过Get-AzVM获取非合规虚拟机的所属订阅名称

解决多订阅场景下未备份VM的订阅名称关联问题

我太懂这种困扰了——明明逻辑看起来没问题,结果所有VM的订阅信息全被最后一个订阅覆盖,实在闹心。核心问题出在你把$currentContext的赋值和VM信息的处理拆成了两个独立循环:第一个循环里$currentContext每次被新的订阅名覆盖,等到第二个循环遍历VM列表时,它只会保留最后一次的赋值,自然所有VM都错用了最后一个订阅的名字。而且Get-AzVM确实不直接返回订阅名称,但我们可以在获取VM的同时就把当前订阅信息绑定到每个VM对象上,彻底解决这个问题。

修改后的代码

$vms_results = @()
$subscriptions = Get-AzSubscription
# 设置未备份VM对应的策略定义ID
$poldef = '013e242c-8828-4970-87b3-ab247555486d'

foreach ($sub in $subscriptions) {
    # 切换到当前订阅,屏蔽不必要的上下文输出
    Set-AzContext -Subscription $sub.Id | Out-Null
    $currentSubName = $sub.Name

    # 获取当前订阅下不符合备份策略的VM资源ID
    $resourceIDs = (Get-AzPolicyState -Filter "PolicyDefinitionName eq '$poldef' and ComplianceState eq 'NonCompliant'").ResourceId

    # 获取目标VM并直接绑定订阅名称,同时生成输出对象
    Get-AzVM | Where-Object{$_.Id -in $resourceIDs} | ForEach-Object {
        $output_data = [PSCustomObject]@{
            vmName = $_.Name
            ResourceGroup = $_.ResourceGroupName
            vmLocation = $_.Location
            vmOS = $_.StorageProfile.OsDisk.OsType
            vmSub = $currentSubName
        }
        $vms_results += $output_data
    }
}

Write-Output "The Following VMs were not able to be backed up, may need investigation"
$vms_results

关键改动说明

  1. 合并循环逻辑:不再先把VM存到临时列表再统一处理,而是在每个订阅的上下文里直接生成带订阅名称的输出对象,从根源上避免了订阅信息丢失的问题。
  2. 直接绑定当前订阅名:在获取到VM的当下,就用$currentSubName(当前循环的订阅名)给输出对象的vmSub赋值,确保每个VM都对应正确的订阅。
  3. 清理冗余输出:给Set-AzContext加上| Out-Null,避免切换上下文时的冗余信息干扰最终结果展示。

这样修改后,每个未备份的VM都会准确显示自己所属的订阅名称,不会再出现全部套用最后一个订阅信息的错误了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 20:32:40