Creating And Restoring Azure Virtual Machine Snapshots For UnManaged Disks

In post I’m going to take a look at creating and restoring Azure Virtual Machine snapshots for unmanaged disks. If you are looking for instructions to create and restore snapshots for managed disks read this post. These instructions are for Azure Resource Manager (ARM) virtual machines, for Azure Service Manager (ASM) virtual machines read this post.

In the case of unmanaged disks the underlying VHD blob can be manipulated like any other blob. This means the blob backing unmanaged OS disks can be overwritten, saving you the trouble of recreating VMs just to revert to a snapshot.

I’m not aware of a way to create snapshots for unmanaged disks in the Azure Portal but there are some tools for example Azure Storage Explorer that can do it.

Update: You can now create and restore snapshots for unmanaged disks in the Azure Portal in the Storage Account blade.

Creating And Restoring Azure Virtual Machine Snapshots For UnManaged Disks

Creating Unmanaged Disk Snapshots

To create a snapshot using PowerShell you retrieve the storage account, reference the blob and create a snapshot. To ensure consistency shutdown your virtual machine beforehand.

$ctx = New-AzureStorageContext -StorageAccountName $StorageAccountName `
  -StorageAccountKey $StorageAccountKey
$blob = Get-AzureStorageBlob -Context $ctx -Container $ContainerName ` 
  -Blob $BlobName 
$snapshot = $blob.ICloudBlob.CreateSnapshot()

You can also create incremental snapshots but it is not available in the PowerShell cmdlets only the Azure Rest API, more info here.

Restore Unmanaged Disk Snapshots

Like I pointed out earlier in the case of unmanaged disks the underlying VHD file is manipulated like any other blob. You can copy the snapshot over its base blob to restore the blob to the snapshot state. This means you can replace the OS disk for a VM without rebuilding it. You can also copy it to another blob to clone your disk.

Since snapshots have the same name as their base blob you can’t retrieve a specific snapshot by its name. The easiest way seems to be retrieving all the snapshots for a blob using the Get-AzureStorageBlob cmdlet and filtering the results to get the specific snapshot you need. For example to retrieve a snapshot by SnapShotTime

$snap = Get-AzureStorageBlob –Context $ctx -Prefix $blobName `
  -Container $containerName | Where-Object {$_.ICloudBlob.IsSnapshot `
  -and $_.SnapshotTime -eq $snapshottime }

Or to retrieve the latest snapshot.

$lastsnap = (Get-AzureStorageBlob –Context $ctx -Prefix $BlobName `
  -Container $ContainerName | Where-Object {$_.ICloudBlob.IsSnapshot `
  -and $_.SnapshotTime -ne $null} | `
  Sort -Property SnapshotTime -Descending )[0]

To restore a snapshot you copy it to a new blob object or you can overwrite an existing blob. This makes it very easy to rollback a VHD to a snapshot without recreating the VM.

$lastsnap = (Get-AzureStorageBlob –Context $ctx -Prefix $BlobName `
  -Container $ContainerName | Where-Object `                                     
  {$_.ICloudBlob.IsSnapshot -and $_.SnapshotTime -ne $null} |
  Sort-Object -Property SnapshotTime -Descending)[0]
$snapshotblob = [Microsoft.WindowsAzure.Storage.Blob.CloudBlob] `    
  $lastsnap.ICloudBlob
$blob.ICloudBlob.BreakLease() 
Start-AzureStorageBlobCopy –Context $ctx -ICloudBlob $snapshotblob `
  -DestBlob $blobName -DestContainer $ContainerName
Get-AzureStorageBlobCopyState -Blob $blobName -Container $ContainerName `
  -Context $ctx -WaitForComplete

Take note if you try to overwrite a VHD that is attached to a VM you will receive an error message indicating there is an existing lease on the VHD. The BreakLease call will remove the lease and the lease will be created again when you start the VM.

Francois Delport

Creating And Restoring Azure Virtual Machine Snapshots For Managed Disks

In post I’m going to take a look at creating and restoring Azure Virtual Machine snapshots for managed disks. These instructions are for Azure Resource Manager (ARM) virtual machines, for Azure Service Manager (ASM) virtual machines read this post. If you are looking for instructions to create and restore snapshots for unmanaged disks read this post.

Why use snapshots?

Snapshots can be used to duplicate a VM relatively quickly since it is faster than copying a blob. You still have to shutdown the source VM to ensure consistency but creating the snapshot only takes a few seconds. Once you have the snapshot you can use it to create new VMs or copies of the VHD blob while the source VM can be powered on again.

Snapshots can also be used as a backup strategy for VMs although Azure Backups provides better functionality with a lot less effort albeit a bit more expensive since you pay for the recovery vault.

The one advantage of snapshots is the ability to overwrite the OS disk without recreating the VM but only for unmanaged disks at the time of writing.

Managed Disk Snapshots

You can create snapshots in the Azure portal by selecting your managed disk from the disks main menu or the disks section on the VM blade.

Azure Virtual Machine Snapshots For Managed Disks

Take note of the export button, you can use it to export the managed disk to a VHD blob which can be used to create unmanaged disks.

To create a snapshot using PowerShell call the New-AzureRmSnapshot command along with New-AzureRmSnapshotConfig to configure the snapshot options.

$mandisk = Get-AzureRmDisk -ResourceGroupName $rsgName -DiskName $diskname
$snapshot = New-AzureRmSnapshotConfig -SourceUri $mandisk.Id `
  -CreateOption Copy -Location $azureregion 
New-AzureRmSnapshot -Snapshot $snapshot -SnapshotName $Name `
  -ResourceGroupName $rsgName

Restoring Managed Disk Snapshots

At the time of writing you couldn’t overwrite or change the managed OS disk on an existing VM but you can create a new managed disk from a snapshot and then create a new VM from the managed disk.

Update: You can now swap a Managed Disk on a VM by replacing the disk Id with another one. This still involves creating another disk from your snapshot and swapping it but at least you don’t have to recreate the VM anymore. Thanks to Ralph Herold for pointing it out to me.

$vm = Get-AzureRmVM -ResourceGroupName osrg -Name vm2 
$disk = Get-AzureRmDisk -ResourceGroupName osrg -Name osbackup 
Set-AzureRmVMOSDisk -VM $vm -ManagedDiskId $disk.Id -Name $disk.Name 
Update-AzureRmVM -ResourceGroupName osrg -VM $vm

I assume you can do the same for data disks using Set-AzureRmVMDataDisk but I didn’t try it yet. Full documentation here.

You can create a new Managed Disk from a snapshot in the Azure Portal or PowerShell. In the Azure Portal select Create New Resource from the main portal menu and search for Managed Disks to create a new Managed Disk. There will be a Source Type dropdown where you can select Snapshot and you will see a list of your snapshots to use as the source for the new Managed Disk.

Azure Virtual Machine Snapshots For Managed Disks

When the create disk operation is completed select the newly created managed disk and create a new VM from the disk.

Azure Virtual Machine Snapshots For Managed Disks

If you want to script it in PowerShell the steps are basically:

  1. Retrieve the snapshot.
  2. Create a new disk configuration specifying the snapshot as the source.
  3. Create a new managed disk from the disk configuration and attach it to a new virtual machine.

If this is a data disk you can attach it to an existing VM instead of creating a new VM but OS disks can only be attached to new VMs.

...

$snapshot = Get-AzureRmSnapshot -ResourceGroupName $rsg `
  -SnapshotName $yoursnapshotname 
 
$diskconf = New-AzureRmDiskConfig -AccountType $storagetype `
  -Location   $snapshot.Location -SourceResourceId $snapshot.Id `
  -CreateOption Copy

$disk = New-AzureRmDisk -Disk $diskconf -ResourceGroupName $rsg `
  -DiskName $osDiskName
$vm = Get-AzureRmVM ...
$vm = Set-AzureRmVMOSDisk -VM $vm -ManagedDiskId $disk.Id `
  -CreateOption Attach -Windows

...

Full script can be found here.

Francois Delport

Create Custom Virtual Machine Image In New Azure Portal

In this post I’ll show you how to create custom virtual machine images in the new Azure Portal for ARM Virtual Machines and Dev Test Labs. Creating custom virtual machine images from your existing virtual machines is a bit different in the new Azure portal compared to the old one. There are lots of resources showing how to do it in PowerShell, Azure CLI and ASM VMs but not so much ARM VMs in the new Azure Portal. For some reason it is not so intuitive that I could just stumbled upon it by exploring the portal.

Create Custom Virtual Machine Image In The Portal

My first thought was to look for a capture image button on the VM blade but there isn’t one, it is now a separate resource on its own blade.

ImagesMenu

If you plan on creating multiple distinct VMs from this image you have to run sysprep before creating the image. If you really want to make clones of this instance you can skip sysprep. The images are created as Managed Disks and you can’t change it so keep the associated cost in mind.

Create Virtual Machine From Custom Image In The Portal

To create a VM from the custom image created earlier you have to go back to the Image blade.

CreateVMFromImage

Create Custom Virtual Machine Image In Dev Test Labs
Firstly Dev Test Labs are pretty awesome, have a look at it if you have to manage multiple VMs for development, testing or training labs. Creating custom images in Dev Test Labs are a bit easier, the “Create custom image” menu item is right on the VM blade.

CreateImageDevTest

You also have the option to run sysprep if you didn’t already or to skip it. Note that the VM will become unusable if you run sysprep.

RunSysPrep

To manage the existing custom images you have to open the “Configuration and policies” blade and you’ll see the “Custom Images” menu item.

ManageCustomImages

Create Virtual Machine From Custom Image In Dev Test Labs

To create a VM from your custom image is very intuitive in Dev Test Labs, when you click on the Add button to create a VM your custom images will be right there with the existing VM templates.

CreateFromCustomImageDevTest

The same applies when you create new Formulas, which is basically creating the new templates in Dev Test Labs.

Francois Delport

Azure Disks And Images

In this post I’m going to explore a few more scenarios around VHDs and images in Azure. If you look at this post I showed how to copy a VM between subscriptions in a semi scripted way. I’ll be extending that script to create an image or hard disk from the copied VHD, but first some more info around blobs.

Blobs

VHDs are stored in Azure Blob Storage and there are 3 types of blobs.

  • Page Blobs
    Used to store VHDs and is optimised for random reading and writing.
  • Block Blobs
    Used to store files that are suitable for streaming and written to once.
  • Append Blobs
    Used for appending data for example log files.

The different types of blobs come into play when you copy VHDs into Azure Blob Storage and depends on the tool you use. If you for instance use Azure PowerShell and the Add-AzureVHD cmdlet the VHD is copied as a page blob. If you use CloudBerry explorer you have to explicitly choose Copy As Page Blob, the default copy will create a block blob. For other tools it could be different so confirm how blobs are copied before you copy 120Gb to Azure just to find out it was the wrong format. Later in the post we will register the VHD as a disk.

Images
Images can be specialised or generalised (SysPrepped) and can contain multiple disks. If you want to create an image that can be used to create more instances of a VM, use a generalised image for example to create instances for a scale out scenario. If you want an exact copy of the VM, use a specialised image, for example to copy it to another subscription or to restore it from a snapshot. When you create an image using PowerShell remember to indicate the OSState. This equates to the check box in the portal, asking if you ran Sysprep.

Azure Disks And Images

If you want to capture an image from a VM you already have in the same subscription, shutdown the VM and save the image.

Save-AzureVMImage -ServiceName VmService -Name VMName -ImageName NewImage -OSState Specialised/Generalised

In the next script I create an image from a VHD I copied into Azure Blob Storage.

$DiskConf = New-AzureVMImageDiskConfigSet

Set-AzureVMImageOSDiskConfig -DiskConfig $DiskConf -HostCaching ReadWrite -OSState Specialised/Generalised -OS "Windows" -MediaLink $vdhurl

$DiskConf.DataDiskConfigurations = new-object Microsoft.WindowsAzure.Commands.ServiceManagement.Model.DataDiskConfigurationList     #work around for a bug

Add-AzureVMImage -ImageName "NewImage" -Label "Easier To Find" -OS Windows -DiskConfig $DiskConf -ShowInGui $true

You can use the old portal to create an image from a VHD, under the virtual machines menu, click in the images tab and choose create new, you can browse to the VHD from there.

From my investigation I could not find a way to change the OSState after the image was created, you might be able to do it by altering the meta data on the blob but I didn’t try it yet. From experience using a specialised image where generalised images are expected doesn’t work, for example creating a new VM from a specialised image that is tagged as generalised just hangs on start up and the boot sequence never completes. Could have been something specific about the VMs I used but it happened twice.

In the old portal you can create a new VM using your existing images by choosing My Images.

Azure Disks And Images

Or pass in the image name in PowerShell.

$VM = New-AzureVMConfig -Name $VmName -InstanceSize $InstanceSize     -ImageName $SourceName

When you create a VM from an image, Azure will create new disks based on the disks referenced by the image, like templates in VMWare.

OS Disks
OS disks contains the disk used for booting, the disk is assumed to be specialised. I did not try to create a VM from one that is generalised yet. If you copied a VHD into blob storage you can create an OS disk using PowerShell.

Add-AzureDisk -DiskName "NewVMBootDisk" -MediaLocation $vdhurl -Label "BootDisk" -OS "Windows"

Or you can use the old portal, under the virtual machines menu, click on the disks tab and choose create new, you can browse to the VHD from there.

Now you can reference this disk to create a new VM.

$VM = New-AzureVMConfig -Name $VmName -InstanceSize $InstanceSize -DiskName "NewVMBootDisk"

You can create a new VM from your OS disk in the old portal by choosing My Disks.

Azure Disks And Images

Once you create a new VM from this disk it is not available to other VMs since it is now attached to the VM you created. This is similar to creating a new VM but attaching an existing disk to it in VMWare.

Data Disks
Data Disks can be attached to a VM but you cannot boot from it. If you copied a VHD into blob storage you can register it as a data disk when attaching it to a VM.

Add-AzureDataDisk -VM $VM -ImportFrom -MediaLocation "VHDUrl" -LUN 1

Francois Delport

Copy Azure Virtual Machines Between Subscriptions

In this post I’m going to show you how to copy Azure Virtual Machines between subscriptions. Copying VMs between subscriptions basically involves copying the VM VHD to a storage account in the other subscription. The same method can be used to copy your VM to another storage account to move it to a different region for instance.

Since this is not a recurring tasks for me this method is not completely automated, it does involve some manual steps. If you need a 100% automated solution please take a look at this post which is completely scripted but much  longer.

Firstly import the publishsettings files for your subscriptions using Get-AzurePublishSettingsFile and Import-AzurePublishSettingsFile if this the first time you are going to use them in PowerShell.

Then execute the following script to copy the VHD, replacing the parts in bold with your values.

#Source VHD
$srcUri="https://yourstorageaccount.blob.core.windows.net/vhds/src_image.vhd"


#Source StorageAccount
$srcStorageAccount="src_storageaccount_name"
$srcStorageKey="src_storage_account_key"

#DestinationStorageAccount
$destStorageAccount="dest_storageaccount"
$destStorageKey="dest_storage_account_key"

#Create the source storageaccount context
$srcContext=New-AzureStorageContext
-StorageAccountName $srcStorageAccount
-StorageAccountKey $srcStorageKey

#Create the destination storageaccount context
$destContext=New-AzureStorageContext
-StorageAccountName $destStorageAccount
-StorageAccountKey $destStorageKey

#Destination ContainerName
$containerName="destinationcontainer"

#Create the  container on the destination
New-AzureStorageContainer -Name $containerName -Context $destContext

#Start the asynchronous copy, specify the source authentication
$copyblob=Start-AzureStorageBlobCopy -srcUri $srcUri -SrcContext $srcContext
-DestContainer $containerName -DestBlob "NewVHD.vhd"
-DestContext $destContext

In my case I was copying inside the same datacentre so it was very quick but if you are copying between regions or copying very large files you can use the snippit below to report the progress of the copy operation.

#Get the status of the copy operation
$copystatus= $copyblob | Get-AzureStorageBlobCopyState


#Output the status every 5 seconds until it is finished
While($copystatus.Status-eq"Pending"){
$copystatus=$copyblob|Get-AzureStorageBlobCopyState
Start-Sleep 5
$copystatus
}

Next on the destination you have to create a disk from the VHD that was copied. In the portal click on Virtual Machines –> Disks –> Create Disk and follow the wizard to create a new disk from the VHD you copied.

Copy Azure Virtual Machines Between Subscriptions

Now you can choose it under My Disks when you create a new VM.

Copy Azure Virtual Machines Between Subscriptions

Tips: In my case both subscriptions had the same name, to differentiate between them edit the .publishsettings file and change the name of one of the subscriptions before importing it.

Francois Delport

Part 4: Restore Virtual Machine Endpoints And Virtual Network Settings

Last week I briefly mentioned you have to re-configure all the settings on your VM when you restore it from a VHD image, you basically only get the hard disk back. Today I’m going to show you a few more details around restoring your VM endpoints and virtual network settings.

If you are completely new to Azure Virtual Networks please read the intro here. Among other things you use them to assign DHCP pools, create VPN connections and setup security groups. The feature I found the most useful was connecting VMs from different cloud services to the same internal network by putting them all on the same VNet. It is a lot simpler than having multiple VMs in the same cloud service and mapping all those external endpoints with different port numbers to the VMs inside the cloud service. By using different cloud services you can also give each VM its own public DNS name.

You can add and remove endpoints after creating your VM but I could not find a way to change the VNet of a VM after it was created, apart from recreating the VM , so it is important to specify the VNet when you create the VM. For example in this script I pipe the VM config, subnet name and static IP address to the New-AzureVM command and I pass the -VNetName parameter with the name of my VNet.

New-AzureVMConfig -Name "TestVM" -InstanceSize "Standard_D2" -ImageName "VMImage" |
Set-AzureSubnet -SubnetNames "Subnet-1" |
Set-AzureStaticVNetIP -IPAddress "10.0.0.10" |
New-AzureVM -ServiceName "NewService" -VNetName "Test VNet"

If you don’t need a static IP you can omit the Set-AzureStaticVNetIP line.

Next up I’m going to map some endpoints to my VM.

Get-AzureVM -ServiceName "NewService" -Name "TestVM" |
Add-AzureEndpoint -Name "Remote Desktop" -Protocol "tcp" -PublicPort 3389 -LocalPort 3389 |
Add-AzureEndpoint -Name "PowerShell" -Protocol "tcp" -PublicPort 5986 -LocalPort 5986 |
Update-AzureVM

I used known port numbers but for a very small amount of extra security you can use different ports. This is a very simple example, I didn’t use load balancing for instance, if you read the documentation you will see how to do that.

Tip: In my environment while I was deleting the existing VM and creating a new one from the imaged VHD I sometimes received this error:

New-AzureVM : Networking.DeploymentVNetAddressAllocationFailure : Unable to allocate the required address spaces for the deployment in a new or predefined subnet that is contained within the specified virtual network.

It happened intermittently and it turned out sometimes Azure took a while to release the static IP address. To try and avoid the problem I stop and deprovision the VM first before deleting it and I also added a retry loop in my PowerShell script. I didn’t have time to test it exhaustively so I can’t confirm that it is working but it looks that way.

Keep in mind this can also happen if another VM is using the same IP address as the one you are trying to assign to your VM. If you look at the list of IP address assigned to your running VMs in the portal you can see if it is already in use.

I didn’t experience this one myself but when I was investigating this error message I came across posts where users received this error but the IP was not in use when they looked at the portal. It turned out that the static IP was assigned at the OS level, never do that, always assign the static IP in the Azure. Just out of interest, you will notice when you assign a static IP to the VM in Azure it doesn’t show in your NIC settings in Windows control panel, everything happens in Azure not the OS.

Francois Delport

Part 3: How To Snapshot And Restore Azure Virtual Machines

UPDATE: For Azure Resource Manager virtual machine snapshots using managed disks read this post and for unmanaged disks read this post.

This post covers Azure Service Manager (ASM) virtual machines.

If you are familiar with VMWare and Hyper-V you’ll know how easy and handy it is to snapshot a VM and return to that snapshot later on. I use it especially when testing installers and automated deployments where you have to run them multiple times on a clean machine.

In this post I’m going to show you how to “snapshot” a VM in Azure and then revert back to that snapshot. I refer to it as a snaphot but Azure doesn’t support snapshots, this is more a workaround that involves capturing the VM virtual hard disk image and storing it in BLOB storage.

In other virtualisation platforms a snapshot captures the disk at that point in time, when you make changes to the file system in your VM your changes are written to a delta file that contains only the modifications from the previous snapshot. This way you can quickly revert back or roll forward between snapshots. This is a very simplified explanation, there is lots more if you want to read. In Azure it is not so quick since the whole VM image is captured and then restored when you revert back to it.

Something else I want to point out before we get started is the difference between generalised and specialised VM images. You can read the whole explanation here. In short you should not clone new VMs from a specialised image since it can lead to problems if your VM is in a domain. It also causes problems with other software like Octopus Deploy since every machine gets a unique certificate when the Tentacle is configured. If you are capturing a VM image to clone it, run SysPrep first to generalise it.

Now on to the fun part, the script. If this is your first time running PowerShell against Azure refer to this post to setup your environment. In PowerShell run the following to capture your image.

Save-AzureVMImage -ServiceName "YourServiceName" -Name "YourVmName" -ImageName "DescriptiveImageName" -OSState Specialized

If you open up the Cloud Explorer in Visual Studio you will see your new VHD image under:
Storage Accounts -> YourStorageAccountName -> Blob Containers -> vhds

Or you can see it in the portal under your storage account.

To revert back to this image you have to delete your existing VM and its disk and  create a new one from this saved VHD image. First make sure your image was created successfully before deleting your VM.

Remove-AzureVM -Name "YourVMName" -ServiceName "YourServiceName" -DeleteVHD

Then create a new VM from the image into your existing service.

New-AzureQuickVM -Name "YourVMName" -ImageName "DescriptiveImageName" -Windows -ServiceName "YourServiceName"  -InstanceSize "Basic_A2" -WaitForBoot

Since this is a new VM your previous Azure configuration will be gone, you have to create the endpoints for this VM again and so on. If you use a virtual network be sure to specify your Vnet when you create the VM as far as I am aware you can’t change it afterwards.

Tip: If you get a “CurrentStorageAccountName is not accessible” error you have to set your default storage account for the subscription by running:

Get-AzureStorageAccount

Take note of the storage account name then run:

Set-AzureSubscription -SubscriptionName "YourSubscriptionName" -CurrentStorageAccountName "YourStorageAccountName" -PassThru

Francois Delport

Part 2: Creating Azure Virtual Machines Using Powershell – The Actual Script

In my previous post I explained what a cloud service is in relation to virtual machines in Azure. I want to mention virtual networks quickly as well since it ties in with your cloud service and virtual machine network configuration before we create a VM.

If you want VMs from multiple cloud services to connect to each other via the internal network instead of public IP addresses you can add them to a virtual network. You also need a virtual network to connect your on-premise infrastructure to Azure via VPN. I will cover the details of virtual networks and VPN in a future post.

When you create a new VM you can choose to add it to an existing virtual network or you can create a new virtual network or you can create it without a virtual network. Is this screenshot I am creating a new VM and using an existing virtual network called “demo”. You will see why this matters when you run the script to create a VM.

VNET

Finally I can get to the actual demo to create a VM in Azure.

You can download Azure PowerShell modules using the Microsoft Web Platform installer. Before you can run PowerShell scripts against your Azure VMs you have to import your publish settings file. Open up PowerShell and run the following command.

Get-AzurePublishSettingsFile

This will launch the Azure Portal in your default browser, sign in and follow the instructions to download your publish settings. Remember to save the file with a .publishsettings extension and put in a directory where you can reach it easily. Back in PowerShell execute the following command to import your file that was downloaded in the previous step.

Import-AzurePublishSettingsFile PathToPublishSettingsFile.publishsettings

And here is the PowerShell script to create a new VM:

$ImageName = "a699494373c04fc0bc8f2bb1389d6106__Windows-Server-2012-R2-20150726-en.us-127GB.vhd"
$VmName = "NewVMName"
$InstanceSize = "Standard_D1"
$AdminUsername = "MyNewAdmin"
$Password = "MyNewPassword"
$Location = "West US"
$ServiceName = $VmName

#Set the image
$Img = Get-AzureVMImage -ImageName $ImageName

#Create the config
$NewVM = New-AzureVMConfig -Name $VmName -InstanceSize $InstanceSize -ImageName $Img.ImageName | Add-AzureProvisioningConfig -Windows -AdminUsername $AdminUsername -Password $Password

#Create the vm
New-AzureVM -VMs $NewVM -WaitForBoot -Verbose -Location $Location -ServiceName $ServiceName

This is a bare bones example, if you look at the documentation there are lots more you can do: Link to MSDN

Parameters Explained

$ImageName: is the name of the image you are using to create this VM. To see which VM images are available, including your own images you created, you can run: Get-AzureVMImage
$VmName: The name for you new VM.
$InstanceSize: The size of the hardware for your VM. To see which instance sizes are available use this link.
$AdminUsername and $Password is the username and password for the administrator user that will be created on this new VM.
$Location: Is the location for this new VM, to get the list of locations run: Get-AzureLocation

NOTE: If you specify the -Location or -AffinityGroup parameters Azure will create a new cloud service for this VM. In this script it will create a new cloud service with the same name as the VM, it is stored in $ServiceName. To add this VM to an existing cloud service specify the -ServiceName parameter but leave out -Location.

I didn’t specify a virtual network for this VM but you can use the -VNetName parameter to do that.

Tip: Make sure your password is valid according to Azure standards. The first one I used wasn’t and the PowerShell script didn’t fail, it happily created the VM but the admin user wasn’t valid and I had to reset the password before I was able to RDP into the machine.
Secondly when you create the storage account you can’t use zone redundant storage for VM disks.

Francois Delport

Part 1: Creating Azure Virtual Machines Using PowerShell

Before I delve into the PowerShell script to create Azure Virtual Machines I want to talk about the relationship between virtual machines and cloud services. This can be a source of confusion and I think it is not so obvious when you look at the Azure portal.

When you create a web role, worker role or VM it is created inside a cloud service. A cloud service is a container that contains roles and a role contains instances. For example you can have a web role that contains 3 instances, in reality this will mean you have 3 windows servers running IIS inside this web role. Being a web role you have some access to the underlying OS but you don’t see the 3 VMs running as you do with compute instances but they are still there, you just see them as web role instances.

When you create a VM it will also reside inside a cloud service as a role but you don’t see a role called virtual machines inside your cloud service, you just see the instances. When you create a new VM you have the option to create a new cloud service or adding this VM to an existing cloud service. The default behaviour is to create a new cloud service and you end up with a 1 to 1 mapping between VMs and cloud services. This works great if you don’t have a need for your VMs to communicate with each other on the private network and it makes mapping endpoints easier since there is only one instance in the cloud service using the ports.

If you look at a cloud service you will see it has a DNS name and the instances inside the cloud service all use this DNS name. The instances have private IP addresses so they can communicate which each other over the private network in the cloud service. If you for instance have 3 web roles the load balancer will redirect port 80 traffic to these 3 web role instances and all 3 will be handling the HTTP requests, great for scaling out your web app. If you have multiple VMs in the cloud service you will see the load balancer setup endpoints mapping external ports to the internal ports on your VM instances.

If you for instance want to remote desktop into these VMs you have the use the port that the load balancer assigned for that VM, by default it will automatically choose a port for RDP but you can specify one if you want. To change the ports you click on the endpoints tab for that VM under the Virtual Machines section in the portal. Remember you can’t just choose any port, you have to make sure the port is not in use already by another instance in that cloud service.

When you create a cloud service you choose the region to host this cloud service, if you then add more VMs to this cloud service you can’t change the location for the VM, it is inherited from the cloud service.

Next time I’ll show the PowerShell script to create a VM.

Francois Delport