将 VHD 上传到 Azure,或将托管磁盘复制到其他区域 - Azure PowerShell

适用于:✔️ Windows VM

本文介绍如何使用 Azure PowerShell 模块将 VHD 从本地计算机上传到 Azure 托管磁盘,或将托管磁盘复制到其他区域。 上传托管磁盘的过程(也称为直接上传)使你能够将最大为 32 TiB 的 VHD 直接上传到托管磁盘。 目前,超级磁盘、高级 SSD v2、高级 SSD、标准 SSD 和标准 HDD 支持直接上传。

若要为 Azure 中的 IaaS VM 提供备份解决方案,你应该使用直接上传方法将客户备份还原到托管磁盘。 从 Azure 外部的源上传 VHD 时,速度取决于本地带宽。 从 Azure VM 上传或复制时,带宽将与标准 HDD 相同。

使用 Microsoft Entra ID 进行安全上传

如果使用 Microsoft Entra ID 来控制资源访问,现在可使用它来限制 Azure 托管磁盘的上传。 此功能在所有区域以正式版产品/服务的形式提供。 当用户尝试上传磁盘时,Azure 会在 Microsoft Entra ID 中验证发出请求的用户的标识,并确认该用户具有所需的权限。 在更高级别,系统管理员可在 Azure 帐户或订阅级别设置策略,确保 Microsoft Entra 标识在允许上传磁盘或磁盘快照之前具有上传所需的权限。 如果对使用 Microsoft Entra ID 进行安全上传有任何疑问,请联系此电子邮件地址:azuredisks@microsoft .com

先决条件

限制

  • 无法将 VHD 上传到空快照。
  • Azure 备份目前不支持使用 Microsoft Entra ID 保护的磁盘。
  • Azure Site Recovery 目前不支持使用 Microsoft Entra ID 保护的磁盘。

分配 RBAC 角色

若要访问受 Microsoft Entra ID 保护的托管磁盘,发出请求的用户必须具有托管磁盘角色的数据操作员角色,或者是具有以下权限的自定义角色

  • Microsoft.Compute/disks/download/action
  • Microsoft.Compute/disks/upload/action
  • Microsoft.Compute/snapshots/download/action
  • Microsoft.Compute/snapshots/upload/action

有关分配角色的详细步骤,请参阅使用 Azure PowerShell 分配 Azure 角色。 若要创建或更新自定义角色,请参阅使用 Azure PowerShell 创建或更新 Azure 自定义角色

入门

可以通过两种方式使用 Azure PowerShell 模块上传 VHD:可以使用 Add-AzVHD 命令(可自动执行大部分过程),也可以使用 AzCopy 手动执行上传。

对于高级 SSD、标准 SSD 和标准 HDD,通常应使用 Add-AzVHD。 但是,如果要上传到超级磁盘或高级 SSD v2,或者需要上传大于 50 GiB 的 VHD,则必须使用 AzCopy 手动上传 VHD 或 VHDX。 使用 AzCopy 可更快地上传 50 GiB 和更大的 VHD,Add-AzVhd 目前不支持上传到超级磁盘或高级 SSD v2。

有关如何将托管磁盘从一个区域复制到另一个区域的指导,请参阅复制托管磁盘

使用 Add-AzVHD

先决条件

  • 安装 Azure PowerShell 模块
  • 已为 Azure 准备了一个 VHD,存储在本地。
    • 在 Windows:无需将 VHD 转换为 VHDx,无需将其转换为固定大小,也无需重设大小以包含 512 字节偏移量。 Add-AZVHD 替你执行这些功能。
      • 必须启用 Hyper-V,Add-AzVHD 才能执行这些功能。
    • 在 Linux 上:必须手动执行这些操作。 有关详细信息,请参阅调整 VHD 大小

上传 VHD

(可选)授予对磁盘的访问权限

如果使用 Microsoft Entra ID 在订阅或帐户级别强制执行上传限制,则只有在具有适当 RBAC 角色或必要权限的用户使用 Add-AzVHD 尝试进行上传时才会成功。 需要分配 RBAC 权限以授予对磁盘的访问权限并生成可写 SAS。

New-AzRoleAssignment -SignInName <emailOrUserprincipalname> `
-RoleDefinitionName "Data Operator for Managed Disks" `
-Scope /subscriptions/<subscriptionId>

使用 Add-AzVHD

以下示例使用 Add-AzVHD 将 VHD 从本地计算机上传到新的 Azure 托管磁盘。 将 <your-filepath-here><your-resource-group-name><desired-region><desired-managed-disk-name> 替换为你的参数:

注意

如果使用 Microsoft Entra ID 强制执行上传限制,请将 DataAccessAuthMode 'AzureActiveDirectory' 添加到 Add-AzVhd 命令的末尾。

# Required parameters
$path = <your-filepath-here>.vhd
$resourceGroup = <your-resource-group-name>
$location = <desired-region>
$name = <desired-managed-disk-name>

# Optional parameters
# $Zone = <desired-zone>
# $sku=<desired-SKU>
# -DataAccessAuthMode 'AzureActiveDirectory'
# -DiskHyperVGeneration = V1 or V2. This applies only to OS disks.

# To use $Zone or #sku, add -Zone or -DiskSKU parameters to the command
Add-AzVhd -LocalFilePath $path -ResourceGroupName $resourceGroup -Location $location -DiskName $name

手动上传

先决条件

若要将 VHD 上传到 Azure,需要创建一个针对此上传过程配置的空托管磁盘。 在创建托管磁盘之前,应了解有关这些磁盘的一些附加信息。

这种托管磁盘有两种独特的状态:

  • ReadyToUpload,表示磁盘已做好上传准备,但尚未生成安全访问签名 (SAS)。
  • ActiveUpload,表示磁盘已做好上传准备,并且已生成 SAS。

注意

在任一状态下,无论实际磁盘类型是什么,都会按标准 HDD 定价对托管磁盘计费。 例如,P10 将按 S10 计费。 在对托管磁盘调用 revoke-access 之前(将磁盘附加到 VM 需要执行此调用),都是如此。

创建空托管磁盘

在创建要上传的空标准 HDD 之前,需要获取要上传的 VHD 的文件大小(以字节为单位)。 可以使用示例代码来这样做,但若要自己操作,可以使用 $vhdSizeBytes = (Get-Item "<fullFilePathHere>").length。 指定 -UploadSizeInBytes 参数时将使用此值。

现在,请在本地 shell 上创建一个要上传的空的标准 HDD,方法是:在 -CreateOption 参数中指定 Upload 设置,并在 New-AzDiskConfig cmdlet 中指定 -UploadSizeInBytes 参数。 然后调用 New-AzDisk 来创建磁盘。

替换 <yourdiskname><yourresourcegroupname><yourregion>,然后运行以下命令:

重要

如果要创建 OS 磁盘,请将 -HyperVGeneration '<yourGeneration>' 添加到 New-AzDiskConfig

如果使用 Microsoft Entra ID 来保护上传,请将 -dataAccessAuthMode 'AzureActiveDirectory' 添加到 New-AzDiskConfig
上传到超级磁盘或高级 SSD v2 时,需要选择目标磁盘的正确扇区大小。 如果使用逻辑扇区大小为 4k 的 VHDX 文件,则必须将目标磁盘设置为 4k。 如果使用逻辑扇区大小为 512 的 VHD 文件,则必须将目标磁盘设置为 512。

不支持逻辑扇区大小为 512k 的 VHDX 文件。

$vhdSizeBytes = (Get-Item "<fullFilePathHere>").length

## For Ultra Disks or Premium SSD v2, add -LogicalSectorSize and specify either 4096 or 512, depending on if you're using a VHDX or a VHD

$diskconfig = New-AzDiskConfig -SkuName 'Standard_LRS' -OsType 'Windows' -UploadSizeInBytes $vhdSizeBytes -Location '<yourregion>' -CreateOption 'Upload'

New-AzDisk -ResourceGroupName '<yourresourcegroupname>' -DiskName '<yourdiskname>' -Disk $diskconfig

如果要上传其他磁盘类型,请将 Standard_LRS 替换为 Premium_LRS、Premium_ZRS、StandardSSD_ZRS、StandardSSD_LRS 或 UltraSSD_LRS。

生成可写 SAS

现在,你已创建了一个针对上传过程配置的空托管磁盘,可以将 VHD 上传到其中了。 若要将 VHD 上传到磁盘,需要一个可写的 SAS,以便将此磁盘作为上传目标引用。

重要

2025 年 2 月 15 日,磁盘和快照的共享访问签名 (SAS) 访问时间将限制为最多 60 天。 尝试生成有效期超过 60 天的 SAS 会导致错误。 已创建的有效期超过 60 天的任何现有磁盘或快照 SAS 在创建日期过去 60 天后可能会停止工作,并且在授权过程中会导致 403 错误。

如果托管磁盘或快照 SAS 的有效期超过 60 天,请撤销其访问权限,并生成请求访问 60 天(5,184,000 秒)或更少时间的新 SAS。 通过使用有效期更短的 SAS 来提高整体安全性。 请在 2025 年 2 月 15 日之前进行这些更改,以防止服务中断。 以下链接可用于查找、撤销和请求新的 SAS。

若要生成空托管磁盘的可写 SAS,请替换 <yourdiskname><yourresourcegroupname>,然后使用以下命令:

$diskSas = Grant-AzDiskAccess -ResourceGroupName '<yourresourcegroupname>' -DiskName '<yourdiskname>' -DurationInSecond 86400 -Access 'Write'

$disk = Get-AzDisk -ResourceGroupName '<yourresourcegroupname>' -DiskName '<yourdiskname>'

上传 VHD 或 VHDX

生成空托管磁盘的 SAS 后,可以使用该 SAS 将托管磁盘设置为上传命令的目标。

使用 AzCopy v10,通过指定生成的 SAS URI 将本地 VHD 或 VHDX 文件上传到托管磁盘。

此上传过程的吞吐量与相应标准 HDD 的吞吐量相同。 例如,如果大小相当于 S4,则最高吞吐量为 60 MiB/秒。 但是,如果大小相当于 S70,则最高吞吐量为 500 MiB/秒。

AzCopy.exe copy "c:\somewhere\mydisk.vhd" $diskSas.AccessSAS --blob-type PageBlob

上传完成后,如果你不再需要将更多数据写入磁盘,请吊销 SAS。 吊销 SAS 会更改托管磁盘的状态,使你可以将磁盘附加到 VM。

替换 <yourdiskname><yourresourcegroupname>,然后运行以下命令:

Revoke-AzDiskAccess -ResourceGroupName '<yourresourcegroupname>' -DiskName '<yourdiskname>'

复制托管磁盘

直接上传还能简化复制托管磁盘的过程。 可以在同一区域中进行复制,或者将托管磁盘复制到其他区域。

以下脚本可自动完成此操作,此过程类似于前面所述的步骤,但由于处理的是现有磁盘,因此存在一些差异。

重要

提供 Azure 中托管磁盘的磁盘大小(以字节为单位)时,必须添加 512 偏移量。 这是因为,Azure 在返回磁盘大小时会省略脚注。 如果你不执行此操作,该副本将失败。 以下脚本中已添加此偏移量。

请将 <sourceResourceGroupHere><sourceDiskNameHere><targetDiskNameHere><targetResourceGroupHere><yourOSTypeHere><yourTargetLocationHere>(例如,位置值为 chinanorth2)替换为自己的值,然后运行以下脚本来复制托管磁盘。

提示

如果要创建 OS 磁盘,请将 -HyperVGeneration '<yourGeneration>' 添加到 New-AzDiskConfig


$sourceRG = <sourceResourceGroupHere>
$sourceDiskName = <sourceDiskNameHere>
$targetDiskName = <targetDiskNameHere>
$targetRG = <targetResourceGroupHere>
$targetLocate = <yourTargetLocationHere>
$targetVmGeneration = "V1" # either V1 or V2
#Expected value for OS is either "Windows" or "Linux"
$targetOS = <yourOSTypeHere>

$sourceDisk = Get-AzDisk -ResourceGroupName $sourceRG -DiskName $sourceDiskName

# Adding the sizeInBytes with the 512 offset, and the -Upload flag
$targetDiskconfig = New-AzDiskConfig -SkuName 'Standard_LRS' -osType $targetOS -UploadSizeInBytes $($sourceDisk.DiskSizeBytes+512) -Location $targetLocate -CreateOption 'Upload' -HyperVGeneration $targetVmGeneration

$targetDisk = New-AzDisk -ResourceGroupName $targetRG -DiskName $targetDiskName -Disk $targetDiskconfig

$sourceDiskSas = Grant-AzDiskAccess -ResourceGroupName $sourceRG -DiskName $sourceDiskName -DurationInSecond 86400 -Access 'Read'

$targetDiskSas = Grant-AzDiskAccess -ResourceGroupName $targetRG -DiskName $targetDiskName -DurationInSecond 86400 -Access 'Write'

azcopy copy $sourceDiskSas.AccessSAS $targetDiskSas.AccessSAS --blob-type PageBlob

Revoke-AzDiskAccess -ResourceGroupName $sourceRG -DiskName $sourceDiskName

Revoke-AzDiskAccess -ResourceGroupName $targetRG -DiskName $targetDiskName 

后续步骤

成功将 VHD 上传到托管磁盘后,即可将磁盘附加到 VM 并开始使用它。

若要了解如何将数据磁盘附加到 VM,请参阅有关此主题的文章:使用 PowerShell 将数据磁盘附加到 Windows VM。 若要将磁盘用作 OS 磁盘,请参阅从专用磁盘创建 Windows VM

如果还有其他问题,请参阅常见问题解答中的上传托管磁盘部分。