When creating images in Azure, Microsoft's best practice is to store those images in an Azure Compute Gallery. This service provides version control and replicas to allow organizations to easily manage their virtual machine deployments at scale. Images may be useful in one subscription, tenant, or Azure cloud, but customers tend to expand their footprint. For example, compliance requirements or global scaling dictates the need for expanded capacity across multiple Azure clouds, tenants, or subscriptions. While an Azure Compute Gallery allows you to share Image Versions across subscriptions, sharing can impact an Image Version. Questions may arise about cost or utilization. Who in the organization owns the charges for the images? Should one entity within an organization own the charges for that image and its replicas? Will deployments scale well if other entities within your organization run deployments simultaneously? The ability to copy an Azure Compute Gallery Image Version between Azure clouds, tenants, and subscriptions addresses these concerns.
This document is intended primarily for Azure engineers and administrators that are responsible for deployments and operational practices.
This solution will copy an Image Version from a Compute Gallery in one Azure cloud, tenant, or subscription to a Compute Gallery in another Azure cloud, tenant, or subscription.
Valid Azure Subscription
Proper RBAC access on the Azure resources
Compute Gallery in source and target subscriptions
Create, grant access, and remove Managed Disks
Deploy and administer an Azure Virtual Machine
Basic knowledge of Azure infrastructure
Basic understanding of PowerShell and running scripts
Deploy a virtual machine using the Image Version in the source Compute Gallery to ensure the image is functional.
There are several factors to consider when migrating an image version such as network capacity, storage capacity, and security. Use the steps below to minimize the time and effort while addressing capacity and security concerns:
Using the Azure Portal, deploy a Windows virtual machine in the source or target Azure cloud, tenant, or subscription. Estimated time: 4 minutes. NOTE: It does not make a difference between the target or source since access across Azure clouds, tenants, or subscriptions is available using Azure PowerShell. For my testing, I chose the following virtual machine properties:
VM Size: Standard_D4ds_v5
OS: Windows 10 Enterprise 21H2
Disk SKU: Premium SSD
Accelerated Networking: Enabled
Stop the virtual machine. Estimated time: 1 minute.
Resize the OS disk to fit the OS and Image Version that you will download to the disk. Estimated time: 20 seconds. NOTE: The OS requires roughly 18GB and most Windows Marketplace images require 127GB.
Start the VM. Estimated time: 1 minute.
Connect to the VM over RDP. Estimated time: 40 seconds (using Bastion).
Open Disk Management, extend the "Windows C:" volume to use the full disk, and close the window. Estimated time: 20 seconds.
Open PowerShell as an Administrator. Estimated time: 25 seconds.
Install the “AZ” module. Estimated time: 4 minutes. NOTE: The two scripts you will run in the upcoming steps will require the AZ module. Also, you will be prompted to install the NuGet provider and to trust the PowerShell Gallery. Be sure to select "Yes" on the prompts or you will be unable to complete the following steps.
Connect to the Azure subscription that contains the source Image Version. Estimated Time: 1 minute.
Download the Export-AzureComputeGalleryImageVersion script from my GitHub repository onto your Azure VM. Estimated Time: 1 minute. NOTE: The file will be blocked by default. Open the file’s properties, select “unblock”, and click “OK”.
Run the script to download the Compute Gallery Image Version to a VHD on your VM. Estimated Time: 25 minutes. NOTE: The “Get-AzStorageBlobContent” cmdlet used in this script optimizes the download speed using multiple internet connections.
Download the Import-AzureComputeGalleryImageVersion script from my GitHub repository onto your Azure VM. Estimated Time: 1 minute.NOTE: The file will be blocked by default. Open the file’s properties, select “unblock”, and click “OK”.
Run the script to upload the VHD to a Compute Gallery Image Version. Estimated Time: 28 minutes. NOTE: The “Add-AzVhd” cmdlet used in this script optimizes the upload speed and has MD5 hash validation built-in.
Disconnect from the Azure subscription. Estimated Time: 10 seconds.
Using the Azure Portal, delete the VM. Estimated Time: 3 minutes.
Post Implementation Validation
Once both scripts have completed without an error, the Image Version will exist in your target Compute Gallery. The script cleans up the Managed Disks that are created as part of the process. To validate the copy of your Image Version, deploy a virtual machine using the Image Version in the target Compute Gallery to ensure the image is functional.
While there are other ways and tools to perform this task, this method is the least risk adverse. If you have any feedback, please leave it below. If you have any suggestions to make the scripts better, please leave an issue on my GitHub repository or submit a pull request with your updates.