Create Azure RM VM Using Existing VHD


TailspinToys Canada have been busy upgrading their on-premises, Azure and Office 365 infrastructure.  Previously Azure resources were moved from classic (Azure Service Manager) to the new Azure Resource Manager (Azure RM).   The VMs, storage accounts and VHDs were migrated.   One of the migration blockers was that multiple availability sets were previously present in one of the cloud services.  This prevented the resource migration, and the additional availability sets had to be removed in the cloud service prior to migrating to Azure RM.  This was all peachy until I wanted to moved some of the migrated VMs into a particular Availability Set in Azure RM for load balancing purposes.  However the Azure RM portal does not let you change the VMs Availability Set on the fly.  Currently Availability Sets are set at machine creation time.  The only way to change the availability set is to delete and re-create the VM.

In this case I wanted to create a new Availability Set for the AD FS servers, so that they could be load balanced in Azure.  However when they were migrated from classic Azure all the VMs were in the same availability set, else they could not be migrated.  Hence the requirement to delete and re-create the VM using the existing VHD.

At this time (November 2016) there is no Azure portal option to do this.  But we have PowerShell….

 

Overview

I wanted to show that this task is not as daunting as it may initially appear, and also provide a simple code sample.  One of the key cmdlets that we are going to use is New-AzureRmVMConfig.

The New-AzureRmVMConfig cmdlet creates a configurable local virtual machine object for Azure. Other cmdlets can be used to configure a virtual machine object, such as Set-AzureRmVMOperatingSystem, Set-AzureRmVMSourceImage, Add-AzureRmVMNetworkInterface, and Set-AzureRmVMOSDisk.

 

This post/script assumes that you have the necessary Azure PowerShell bits installed, and that you have permissions to the resources.  It also assumes that you are connected, typically using something like the below:

Login-AzureRmAccount
Get-AzureRmSubscription
Select-AzureRmSubscription
Get-AzureRmContext

 

For those coming from the older Azure cmdlets, note that the ones used here are very familiar.  They contain the “RM” string to indicate they work with Resource Manager.  There is still a need to have both classicand RM tools since they are both currently supported.

We need to provide all of the necessary configuration details to the cmdlets.  Things like which NIC to use, where the VHD is, which Resource Group is used for each item etc.  Note that the resources may be split across different Resource Groups.  You will need to verify the specifics for your environment, and update the script with the correct information.

The script is split out into different sections

# Global Variables

# Compute Variables

# Network Variables

# Network Script

# Compute Script

 

There is an option to either re-use the existing NIC or to create a new one (assuming that the original was previously deleted).  One issue which I noted was when re-creating the VM with the existing VHD and re-using the NIC, Azure RM did not seem to like this when I also changed the availability set to match that of my internal load balancer.  Hence I just deleted the old NIC and created a new NIC.  The error received was:

Canada/providers/Microsoft.Compute/virtualMachines/Tail-CA-STS2 is using different Availability Set than other Virtual Machines connected to the Load Balancer(s) Tail-CA-DC-1-PublicLoadBalancer. ErrorCode: VmIsNotInSameAvailabilitySetAsLb

 

Script Download

The sample script can be downloaded from the TechNet scripting gallery.  It is to be considered sample code, and requires you to update/complete all of the relevant sections.

Script To Create Azure VM Using Resource Manager

 

Running ze Script

You will need to gather the required information to populate the script.  Do this by editing the variables to the correct values from your own subscription.

After double-checking your changes, time to let it rip.  Connect to Azure RM, and run the script.

The below is an example of re-creating a VM.  Note that we check to see what VMs are present initially in the given Resource Group.  Initially there are none.  Then we run the script which was edited to the correct values which creates the VM using an existing VHD.

Create Azure RM VM Using Exisitng VHD Script

Note that once the script finished, there is a VM listed.  I have removed the SubscriptionID from the image, and also highlighted the VM name so that it stands out somewhat.

A couple of times I have had the below, which I happily ignore as the machine was created and was functional.

New-AzureRMVM : Long running operation failed with status 'Failed'.
ErrorCode: VMAgentStatusCommunicationError
ErrorMessage: VM 'Tail-CA-ADFS1' has not reported status for VM agent or extensions. Please verify the VM has a
running VM agent, and can establish outbound connections to Azure storage.

 

You may also note that the computer name is not listed in the Essentials section of the Azure RM portal.  Note that there is a “-“ in the highlighted box below, where the computer name should be present.

image

This is discussed in this forum, and a fix is pending at this time.

 

Bootnote

There are some additional community scripts and tools out there.  For example Paulo Marques published the below:

Additional Script Resource To Manage RM Availability Sets

 

This is not an exhaustive list and I fully expect there to be some great options added via the comments!

 

Cheers,

Rhoderick

Comments (5)

  1. Renzo Frassinelli says:

    Hello Rhoderick, I ran into a problem that forced me to try creating a VM from an existing VHD.

    Problem is I after I run the script and create the VM instead of using the OS installation found in the VHD azure completely overwrites the virtual hard disk, leaving me with a fresh OS install.

    Is this the inteded behaviour or there's a problem?
    I used the provided PS script, didn't change anything besides the Resource, VM, etc. names and I didn't secify an availability set.

    1. Hi Renzo,

      That is not the behaviour I see - it uses the existing OS disk without trashing the previous build. In most of the AD FS or Exchange labs I have in Azure there is only a single disk, and that is the OS disk. So I would have noticed that Exchange had vanished or the like.

      Cheers,
      Rhoderick

  2. Douglas Spindler says:

    I have a VMware VMDK I converted to VHD and uploaded to a storage blob. (Linux box) Can I make a Azure RM from that VHD? Will this script do it?

  3. Neil says:

    Hello, I am trying to use this script to re-create a VM however, the disk in question was created as a 'managed disk' and as such I am not sure what to provide for the $OSDiskUri variable since I don't have/cannot find a blob storage VHD address. Is there a way to do this, or do I need to change the -VHDUri parameter to something specific to managed disks?

    Thanks

Skip to main content