Dave Rend贸n Microsoft Azure MVP, embracing and fostering tech intensity to benefit society and thrive in a digital world.

Move VHD to Azure and create Virtual Machine image using Powershell Az Module

3 min read

Move VHD to Azure and create the Virtual Machine image using Powershell Az Module - wikiazure

This article intends to help you move your VHD to Azure and create the Virtual Machine image using Powershell Az Module.

Issue

This article is provided as an alternative solution for migrating a KEMP LoadMaster virtual machine on an Azure subscription, however it applies to any vhd that need to be migrated to Azure.

In case you want to use the AzureRM module you can check this article: https://wikiazure.com/compute/mover-vhd-hacia-azure-usando-powershell/


Solution

Move your VHD to Azure and create the virtual machine image object from the OS Disk

Prerequisites:

Steps to move VHD to Azure and create Virtual Machine image using PowerShell Az Module

  • Open Powershell on your local computer and access to the Azure subscription through the command:
Connect-AzAccount
  • Get your subscription Id with the cmd below:
Get-AzSubscription
  • To simplify the process let’s use the variables below:
$subscriptionName = "AzureCloud"
$subscriptionId = "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx"
$tenantId ="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx"
$resourceGroupName = 'Your-Resource-Group-Name'
$location = 'EastUS'
$vhdName = 'Your-VHD-Name.vhd'
$imageName = 'Your-Image-Name'
$containerName = "Your-Container-Name"
$storageAccountName = "Your-Storage-Account-Name"
  • Now set the subscription to use in the current session with the following command:
Set-AzContext -SubscriptionId $subscriptionId
  • Proceed to create a Storage Account and set the context  through the following command:
$storageAccount = New-AzStorageAccount -ResourceGroupName $resourceGroupName -AccountName $storageAccountName -SkuName Standard_LRS -Location $location
$ctx = $storageAccount.Context
  • Now let’s create the storage container:
New-AzStorageContainer -Name $containerName -Context $ctx -Permission blob
  • Set the local path from the vhd
$localPath = 'Path-to-Your-VHD-File.vhd'
  • Assign a variable to name the VHD:
$vhdName =聽'your-vhd-file.vhd'

Set the url of the image and move the vhd, also use the -overwrite option since process might fail sporadically. “overwrite” solves the error “The pipeline was not run because a pipeline is already running.”

$urlOfUploadedImageVhd = ('https://' + $storageAccountName + '.blob.core.windows.net/' + $containerName  + '/' + $vhdName)
Add-AzVhd -ResourceGroupName $resourceGroupName -Destination $urlOfUploadedImageVhd `
-LocalFilePath $localPath -OverWrite

Add-AzureRmVhd cmdlet uploads on-premises virtual hard disks, in .vhd file format, to a blob storage account as fixed virtual hard disks

There are other optional parameters that can be utilized: 

  • AsJob: Run cmdlet in the background and return a Job to track progress.
  • BaseImageUriToPatch: Specifies the URI to a base image blob in Azure Blob Storage
  • DefaultProfile: The credentials, account, tenant, and subscription used for communication with Azure.
  • NumberOfUploaderThreads: Specifies the number of uploader threads to be used when uploading the .vhd file.
  • OverWrite: Indicates that this cmdlet overwrites an existing blob in the specified destination URI, if one exists.

The VHD migration process will start right away and depending on the size it could take a couple of minutes:

  • Create a managed image from the uploaded VHD
$imageConfig = New-AzImageConfig -Location $location
  •  Set the managed disk from the image
$imageConfig = Set-AzImageOsDisk -Image $imageConfig -OsType Windows -OsState Generalized `
    -BlobUri $urlOfUploadedImageVhd
  • Now proceed to generate the image: 
$image = New-AzImage -ImageName $imageName -ResourceGroupName $resourceGroupName -Image $imageConfig

Complete script to move VHD to Azure and create virtual machine image using Powershell Az Module

锘緾onnect-AzAccount
$subscriptionName = "AzureCloud"
$subscriptionId = "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx"
$tenantId ="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx"
$resourceGroupName = 'Your-Resource-Group-Name'
$location = 'EastUS'
$vhdName = 'Your-VHD-Name.vhd'
$imageName = 'Your-Image-Name'
$containerName = "Your-Container-Name"
#Be sure to provide a valid storage account name. Storage account name must be between 3 and 24 characters in length and use numbers and lower-case letters only.
$storageAccountName = "Your-Storage-Account-Name"

#Set the Subscription to use in the current session
Set-AzContext -SubscriptionId $subscriptionId

#create new storage account
$storageAccount = New-AzStorageAccount -ResourceGroupName $resourceGroupName -AccountName $storageAccountName -SkuName Standard_LRS -Location $location
$ctx = $storageAccount.Context

#create storage container
New-AzStorageContainer -Name $containerName -Context $ctx -Permission blob

#set the local path from the vhd
$localPath = 'Path-to-Your-VHD-File.vhd'

# set the url of the image and move the vhd, also use the -overwrite option since process might fail sporadically
# -overwrite solves the error "The pipeline was not run because a pipeline is already running."
$urlOfUploadedImageVhd = ('https://' + $storageAccountName + '.blob.core.windows.net/' + $containerName  + '/' + $vhdName)
Add-AzVhd -ResourceGroupName $resourceGroupName -Destination $urlOfUploadedImageVhd `
-LocalFilePath $localPath -OverWrite

# Create a managed image from the uploaded VHD
$imageConfig = New-AzImageConfig -Location $location

#set the managed disk from the image, ensure to select the correct OS Type (Windows or Linux)
$imageConfig = Set-AzImageOsDisk -Image $imageConfig -OsType Windows -OsState Generalized `
    -BlobUri $urlOfUploadedImageVhd

#Create image
$image = New-AzImage -ImageName $imageName -ResourceGroupName $resourceGroupName -Image $imageConfig

Github Repository

Feel free to contribute – https://github.com/daveRendon/Move-VHD-to-Azure-and-Create-VM-Image-using-PowerShell

Troubleshooting

Discover questions

  1. Was the VHD uploaded to Azure Cloud or the OS on the VHD is from Azure Marketplace?
  2. What Operation System/version is installed on the VHD?
  3. Did you install Azure Guest Agent on the OS? 
  4. Was the VHD OS generalized before shutdown? 

You should be able to identify what Linux OS type/version is running on your local machine, install Guest Agent, generalize the OS before importing it to Azure Cloud.

Steps you may apply in order to fix the issue

  1. Identify OS type/version, and install on it Guest Agent. Please review an article: Linux distributions endorsed on Azure
  2. Generalize the OS: How to create an image of a virtual machine or VHD
  3. Review the Azure documentation in order to prepare the OS. Following article contains steps how to prepare the OS and install required applications:       Understanding and using the Azure Linux Agent
  4.  Fix the size of the vhd, that is, the VHD size integer, i.e. 200GB, it cannot be 200.5GB or 200.05GB. 
  5.  Ensure that blob is formatted as VHD

See Also

Dave Rend贸n Microsoft Azure MVP, embracing and fostering tech intensity to benefit society and thrive in a digital world.

Leave a Reply

Your email address will not be published. Required fields are marked *