多订阅场景下如何通过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
关键改动说明
- 合并循环逻辑:不再先把VM存到临时列表再统一处理,而是在每个订阅的上下文里直接生成带订阅名称的输出对象,从根源上避免了订阅信息丢失的问题。
- 直接绑定当前订阅名:在获取到VM的当下,就用
$currentSubName(当前循环的订阅名)给输出对象的vmSub赋值,确保每个VM都对应正确的订阅。 - 清理冗余输出:给
Set-AzContext加上| Out-Null,避免切换上下文时的冗余信息干扰最终结果展示。
这样修改后,每个未备份的VM都会准确显示自己所属的订阅名称,不会再出现全部套用最后一个订阅信息的错误了。
内容的提问来源于stack exchange,提问作者EG92
相关产品推荐
相关产品推荐

