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

如何通过PowerShell在Azure订阅间复制捕获镜像(无需创建VM)

当然可以搞定!不用折腾创建VM,就能跨Azure订阅复制你捕获的镜像,我给你整理了两套PowerShell方案,步骤清晰,你跟着来就行:

前提准备
  • 确保你安装了最新版的Az PowerShell模块(没装的话跑这个命令:Install-Module -Name Az -AllowClobber -Scope CurrentUser)
  • 拥有源订阅和目标订阅的参与者或更高权限
  • 提前在目标订阅建好一个资源组,要是用VHD导出法的话还得准备好存储账户(和源镜像同区域最佳)

方法一:利用快照中转(推荐,步骤更高效)

这种方法是先给源镜像的底层托管磁盘打快照,把快照复制到目标订阅,最后从快照生成新的自定义镜像,全程不用导出VHD。

步骤1:登录Azure并切换到源订阅

# 登录Azure账户
Connect-AzAccount

# 替换成你的源订阅ID
$sourceSubscriptionId = "xxxx-xxxx-xxxx-xxxx"
Set-AzContext -Subscription $sourceSubscriptionId

步骤2:获取源镜像的底层磁盘ID

# 替换成你的源镜像名称和资源组
$sourceImageName = "你的捕获镜像名称"
$sourceResourceGroupName = "源资源组名称"

$sourceImage = Get-AzImage -ResourceGroupName $sourceResourceGroupName -ImageName $sourceImageName
$sourceDiskId = $sourceImage.StorageProfile.OsDisk.ManagedDisk.Id

步骤3:在源订阅创建磁盘快照

# 自动生成带时间戳的快照名称,避免重复
$snapshotName = "ImageSnapshot-$(Get-Date -Format 'yyyyMMddHHmmss')"
$snapshotResourceGroupName = $sourceResourceGroupName

# 创建快照配置并生成快照
$snapshotConfig = New-AzSnapshotConfig -SourceUri $sourceDiskId -Location $sourceImage.Location -CreateOption Copy
New-AzSnapshot -Snapshot $snapshotConfig -SnapshotName $snapshotName -ResourceGroupName $snapshotResourceGroupName

步骤4:把快照复制到目标订阅

# 切换到目标订阅
$targetSubscriptionId = "yyyy-yyyy-yyyy-yyyy"
Set-AzContext -Subscription $targetSubscriptionId

# 替换成你的目标资源组名称(提前建好)
$targetResourceGroupName = "目标资源组名称"

# 切回源订阅获取快照对象
Set-AzContext -Subscription $sourceSubscriptionId
$snapshot = Get-AzSnapshot -ResourceGroupName $snapshotResourceGroupName -SnapshotName $snapshotName

# 复制快照到目标订阅
$targetSnapshotName = $snapshotName
New-AzSnapshot -ResourceGroupName $targetResourceGroupName -SnapshotName $targetSnapshotName -Location $snapshot.Location -CreateOption Copy -SourceResourceId $snapshot.Id

步骤5:在目标订阅从快照生成自定义镜像

# 切回目标订阅
Set-AzContext -Subscription $targetSubscriptionId

# 自动生成带时间戳的目标镜像名称
$targetImageName = "Copied-Image-$(Get-Date -Format 'yyyyMMddHHmmss')"

# 先从快照创建临时托管磁盘
$diskConfig = New-AzDiskConfig -Location $snapshot.Location -CreateOption Copy -SourceResourceId (Get-AzSnapshot -ResourceGroupName $targetResourceGroupName -SnapshotName $targetSnapshotName).Id
$managedDisk = New-AzDisk -Disk $diskConfig -ResourceGroupName $targetResourceGroupName -DiskName "Temp-Disk-For-Image"

# 基于临时磁盘创建自定义镜像
$imageConfig = New-AzImageConfig -Location $snapshot.Location
# 如果是Linux镜像,把Windows改成Linux
Set-AzImageOsDisk -Image $imageConfig -OsType Windows -OsState Generalized -ManagedDiskId $managedDisk.Id
New-AzImage -Image $imageConfig -ImageName $targetImageName -ResourceGroupName $targetResourceGroupName

# 可选:删除临时磁盘节省成本
Remove-AzDisk -ResourceGroupName $targetResourceGroupName -DiskName "Temp-Disk-For-Image" -Force

方法二:导出镜像到VHD再导入(适合需要保留VHD备份的场景)

如果需要把VHD单独备份,或者跨区域复制(可以先导出到源区域存储,再复制到目标区域),可以用这套方案。

步骤1:登录并获取源镜像信息

Connect-AzAccount
$sourceSubscriptionId = "xxxx-xxxx-xxxx-xxxx"
Set-AzContext -Subscription $sourceSubscriptionId

$sourceImageName = "你的捕获镜像名称"
$sourceResourceGroupName = "源资源组名称"
$sourceImage = Get-AzImage -ResourceGroupName $sourceResourceGroupName -ImageName $sourceImageName

步骤2:生成镜像磁盘的SAS访问链接

# 替换成你的源存储账户信息(和镜像同区域)
$sourceStorageAccountName = "源存储账户名称"
$sourceStorageResourceGroupName = "源存储账户所在资源组"
$containerName = "vhds"

# 获取存储账户上下文
$storageAccount = Get-AzStorageAccount -ResourceGroupName $sourceStorageResourceGroupName -Name $sourceStorageAccountName
$context = $storageAccount.Context

# 创建存储容器(如果不存在)
if (-not (Get-AzStorageContainer -Name $containerName -Context $context -ErrorAction SilentlyContinue)) {
    New-AzStorageContainer -Name $containerName -Context $context -Permission Blob
}

# 生成有效期24小时的SAS链接
$sasUri = Grant-AzDiskAccess -ResourceGroupName $sourceResourceGroupName -DiskId $sourceImage.StorageProfile.OsDisk.ManagedDisk.Id -DurationInSecond (New-TimeSpan -Hours 24).TotalSeconds -Access Read

步骤3:把VHD复制到目标订阅的存储账户

# 切换到目标订阅
$targetSubscriptionId = "yyyy-yyyy-yyyy-yyyy"
Set-AzContext -Subscription $targetSubscriptionId

# 替换成你的目标存储账户信息
$targetStorageAccountName = "目标存储账户名称"
$targetStorageResourceGroupName = "目标存储账户所在资源组"
$targetContainerName = "vhds"

$targetStorageAccount = Get-AzStorageAccount -ResourceGroupName $targetStorageResourceGroupName -Name $targetStorageAccountName
$targetContext = $targetStorageAccount.Context

# 创建目标容器(如果不存在)
if (-not (Get-AzStorageContainer -Name $targetContainerName -Context $targetContext -ErrorAction SilentlyContinue)) {
    New-AzStorageContainer -Name $targetContainerName -Context $targetContext -Permission Blob
}

# 启动VHD复制
$targetVhdName = "Copied-Image.vhd"
Start-AzStorageBlobCopy -AbsoluteUri $sasUri.AccessSAS -DestContainer $targetContainerName -DestBlob $targetVhdName -DestContext $targetContext

# 等待复制完成(每30秒检查一次状态)
while ((Get-AzStorageBlobCopyState -Container $targetContainerName -Blob $targetVhdName -Context $targetContext).Status -eq "Pending") {
    Write-Host "VHD复制中,请稍等..."
    Start-Sleep -Seconds 30
}
Write-Host "VHD复制完成!"

步骤4:在目标订阅从VHD创建自定义镜像

# 获取目标VHD的访问链接
$targetVhdUri = (Get-AzStorageBlob -Container $targetContainerName -Blob $targetVhdName -Context $targetContext).ICloudBlob.Uri.AbsoluteUri

# 创建镜像配置
$imageConfig = New-AzImageConfig -Location $sourceImage.Location
# Linux镜像记得改成OsType Linux
Set-AzImageOsDisk -Image $imageConfig -OsType Windows -OsState Generalized -BlobUri $targetVhdUri

# 生成自定义镜像
$targetImageName = "Imported-Image-$(Get-Date -Format 'yyyyMMddHHmmss')"
$targetResourceGroupName = "目标资源组名称"
New-AzImage -Image $imageConfig -ImageName $targetImageName -ResourceGroupName $targetResourceGroupName

注意事项
  • 所有占位符(订阅ID、资源组名称、镜像名称等)记得替换成你的实际信息
  • 如果是Linux镜像,把所有-OsType Windows改成-OsType Linux
  • 快照和VHD复制默认要求源和目标资源在同一区域,如果需要跨区域,复制快照时可以指定-Location参数为目标区域
  • 操作完成后,记得删除源订阅的快照、临时VHD等冗余资源,避免不必要的成本

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:40:13