如何通过PowerShell Runbook将Azure VM快照跨订阅存储至另一订阅的RG
解决Azure PowerShell循环中切换订阅上下文不生效的问题
问题核心原因
Set-AzContext修改的是当前PowerShell会话的全局上下文,但在foreach循环中频繁切换时,可能因命令执行时序或上下文未及时刷新,导致后续命令仍沿用旧上下文。更可靠的做法是绕过全局上下文切换,直接在创建快照的命令中指定目标订阅参数。
解决方案:直接指定目标订阅/使用上下文参数
无需依赖Set-AzContext,在创建快照的命令中通过-Subscription参数指定目标订阅ID,或使用-DefaultProfile传递预先获取的目标订阅上下文,确保命令精准指向目标订阅的资源组。
示例代码
- 预先准备目标订阅信息:
# 替换为你的目标订阅ID和资源组名称 $targetSubId = "xxxx-xxxx-xxxx-xxxx" $targetRGName = "你的目标资源组名称" # 可选:预先获取目标订阅上下文,后续命令可复用 $targetContext = Get-AzContext -Subscription $targetSubId
- 遍历源VM并创建快照(直接指定订阅):
# $sourceVMs 是你已获取的源订阅中的VM数组 foreach ($vm in $sourceVMs) { # 获取源订阅中的系统盘 $sourceSubId = $vm.Id.Split('/')[2] $osDisk = Get-AzDisk -ResourceGroupName $vm.ResourceGroupName -DiskName $vm.StorageProfile.OsDisk.Name -Subscription $sourceSubId # 创建系统盘快照配置 $osSnapshotConfig = New-AzSnapshotConfig -SourceUri $osDisk.Id -Location $vm.Location -CreateOption Copy # 直接指定目标订阅和RG创建快照 New-AzSnapshot -Snapshot $osSnapshotConfig -SnapshotName "OS-Snap-$($vm.Name)" -ResourceGroupName $targetRGName -Subscription $targetSubId # 遍历数据盘并创建快照 foreach ($dataDisk in $vm.StorageProfile.DataDisks) { $dataDiskObj = Get-AzDisk -ResourceGroupName $vm.ResourceGroupName -DiskName $dataDisk.Name -Subscription $sourceSubId $dataSnapshotConfig = New-AzSnapshotConfig -SourceUri $dataDiskObj.Id -Location $vm.Location -CreateOption Copy New-AzSnapshot -Snapshot $dataSnapshotConfig -SnapshotName "Data-Snap-$($vm.Name)-Lun$($dataDisk.Lun)" -ResourceGroupName $targetRGName -Subscription $targetSubId } }
- 可选:使用
-DefaultProfile传递上下文:
如果预先获取了$targetContext,创建快照时可替换为:
New-AzSnapshot -Snapshot $osSnapshotConfig -SnapshotName "OS-Snap-$($vm.Name)" -ResourceGroupName $targetRGName -DefaultProfile $targetContext
额外注意事项
- 确保当前登录账号对源订阅有磁盘读取权限,对目标订阅有快照创建权限
- 若目标资源组不存在,需先通过
New-AzResourceGroup创建(需指定目标订阅)
内容的提问来源于stack exchange,提问作者Sahil Wadehra
相关产品推荐
相关产品推荐

