Azure: Moving VHD to Azure with PowerShell and create VM image
Credits
Original Article: https://wikiazure.com/compute/mover-vhd-hacia-azure-usando-powershell/
Introduction
This article is a guide for moving a VHD to Azure using PowerShell with Azure Resource Manager 5.1 module. Then in the Azure portal, we will create an image from the VHD, this will help us to be able to provision VMs from that image.
Issue
This article is provided as an alternative solution for provisioning a KEMP LoadMaster virtual machine on an Azure subscription with the Enterprise Agreement in case there are limitations for the current region to provision the KEMP LoadMaster directly from the Azure marketplace.
Note: We can move an exported VHD from a local virtualization tool or from another cloud.
The use of managed disks for the new virtual machine simplifies the administration of the virtual machine and provides better availability when the virtual machine is placed in an availability set.
Solution
Move VHD to Azure using PowerShell and create an image object from the OS Disk
Prerequisites:
- Active Azure subscription - Azure Free Account
- Azure Powershell 5.x - Azure Resource Manager Module
- VHD of the KEMP LoadMaster - Download VHD
- A resource group previously provisioned in the Azure subscription - see Creating Resource Groups using PowerShell
- Validate that the VHD is fixed size, that means it cannot be 10.1GB or 10.01GB in that case expand the size of the disk to 11GB using hyper-v manager
Steps to move VHD to Azure using PowerShell
1. We will open Powershell on our local computer and access our Azure subscription through the command:
"AzureRM.Profile \ Login-AzureRmAccount"
2. To simplify the process we will use two variables: The name of the Azure subscription and the ID of the Azure subscription by executing the following commands (replace the name and ID of your subscription):
$Subscription = "Your Subscription Name"
$SubscriptionId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
3. We will select the current subscription as Default, for that we execute the following command:
"Get-AzureRmSubscription -SubscriptionId" 4d278909-xxxx-xxxx-xxxx-xxxxxxxx "-TenantId" 683bfafa-xxxx-xxxx-a787-xxxxxxxxx "| Set-AzureRmContext"
4. Proceed to create a Storage Account / Storage Account through the following command:
$storageAccount = New-AzureRmStorageAccount -ResourceGroupName "DRendon" `
-Name "kempvdhtestingdr" `
-SkuName Standard_LRS `
-Location "eastus"
$ctx = $ storageAccount.Context
5. Now we are going to generate the container for our blob storage:
$containerName = "kempvdhcontainerdr"
new-azurestoragecontainer -Name $ containerName -Context $ctx -Permission blob
6. Store in a variable the location of the VHD:
$localPath = 'C:\Users\daver\Downloads\VLM-trial\LoadMaster-VLM-Microsoft-HyperV\vlm2.vhd'
7. Assign a variable to name the VHD:
$vhdName = 'kempVhdtest.vhd'
8. Proceed to move the VHD to the blob storage:
$urlOfUploadedImageVhd = ('https://kempvdhtestingdr.blob.core.windows.net/kempvdhcontainerdr' + '/' + $vhdName)
Add-AzureRmVhd -ResourceGroupName "DRendon" -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 we can make use of:
- 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:
Once the upload has been successful you should see something like this:
Now there are 2 options to create the image: from PowerShell or from the Azure Portal.
Creating the image of the Virtual Machine
Option 1. Creating the image of the Virtual Machine using PowerShell
1. Let's create an image object and then store it in the variable $ imageConfig
$location = 'EastUS'
$imageConfig = New-AzureRmImageConfig -Location $ location
2. Then we are going to set the properties of the operating system disk in the object of the image using the Set-AzureRmImageOsDisk command:
$imageConfig = Set-AzureRmImageOsDisk -Image $imageConfig -OsType Windows -OsState Generalized `
-BlobUri $urlOfUploadedImageVhd
3. Now proceed to generate the image:
$image = New-AzureRmImage -ImageName $imageName -ResourceGroupName $resourceGroupName -Image $imageConfig
Option 2. Creating the image of the Virtual Machine in Azure
Once the migration process is completed, go to the storage account to verify that the VHD is correctly listed:
2. Now go create a new resource, search for "image" then click on the image as shown below:
3. Provide the parameters required to provision the image from the VHD as follows:
You will see a notification if the image was created correctly:
Now we can create the virtual machines from this image when we need it:
Script Download
Here is the complete script on VHD migration with Azure Powershell 5.x, you can also download it from here: https://gallery.technet.microsoft.com/Move-your-VHD-to-Azure-e16f9fd6
AzureRM.Profile\Login-AzureRmAccount
$subscriptionName = "Your Subscription Name"
$subscriptionId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
$tenantId ="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
$resourceGroupName = 'DRendon'
$location = 'EastUS'
$vhdName = 'kemp360central-v1.25.vhd'
$imageName = 'kempcentral25'
$containerName = "kempcentraldrtestcontainer"
$storageAccountName = "kempcentraldrtest"
Select-AzureRmSubscription -SubscriptionId $subscriptionId
#Select your default subscription on ARM
Get-AzureRmSubscription -SubscriptionId $subscriptionId -TenantId $tenantId | Set-AzureRmContext
#create new storage account
$storageAccount = New-AzureRmStorageAccount -ResourceGroupName $resourceGroupName -Name $storageAccountName -SkuName Standard_LRS -Location $location
$ctx = $storageAccount.Context
#create container
new-azurestoragecontainer -Name $containerName -Context $ctx -Permission blob
#set the local path from the vhd
$localPath = 'C:\Users\daver\Downloads\kemp360central\kemp360central-v1.25.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 Add-AzureRmVhd : The pipeline was not run because a pipeline is already running.
# Pipelines cannot be run concurrently
$urlOfUploadedImageVhd = ('https://' + $storageAccountName + '.blob.core.windows.net/' + $containerName + '/' + $vhdName)
Add-AzureRmVhd -ResourceGroupName $resourceGroupName -Destination $urlOfUploadedImageVhd `
-LocalFilePath $localPath -OverWrite
# Create a managed image from the uploaded VHD
$imageConfig = New-AzureRmImageConfig -Location $location
#set the managed disk from the image
$imageConfig = Set-AzureRmImageOsDisk -Image $imageConfig -OsType Windows -OsState Generalized `
-BlobUri $urlOfUploadedImageVhd
$image = New-AzureRmImage -ImageName $imageName -ResourceGroupName $resourceGroupName -Image $imageConfig
Github Repository
Feel free to contribute - https://github.com/daveRendon/Moving-VHD-to-Azure-with-PowerShell-and-create-VM-image/blob/master/src/moving-vhd-to-Azure-create-vm-image.ps1
Troubleshooting
Discover questions
- Was the VHD uploaded to Azure Cloud or the OS on the VHD is from Azure Marketplace?
- What Operation System/version is installed on the VHD?
- Did you install Azure Guest Agent on the OS?
- Was the VHD OS generalized before shutdown?
You should be able to identify what Linux OS type/version is running on your PC, install Guest Agent, generalize the OS before importing it to Azure Cloud.
Steps you may apply in order to fix the issue
- Identify OS type/version, and install on it Guest Agent. Please review an article: Linux distributions endorsed on Azure
- Generalize the OS: How to create an image of a virtual machine or VHD
- 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
- Fix the size of the vhd, that is, the VHD size integer, i.e. 200GB, it cannot be 200.5GB or 200.05GB.
- Ensure that blob is formatted as VHD
See Also
- Prepare a Windows VHD or VHDX to upload to Azure
- How to use Packer to create Windows virtual machine images in Azure
- List of supported images for Azure - The list says for stack but it is applicable for all of Azure.
Other Languages:
Spanish (es-MX): https://social.technet.microsoft.com/wiki/contents/articles/52416.mover-vhd-hacia-azure-usando-powershell-arm-es-mx.aspx