Azure ARM: naïve single VM deployment

The aim is to get a real simple VM deployment working using a json template, and in doing that to sacrifice any guidelines on authoring best practice, so we can focus on getting familiar with the nuts and bolts of ARM deployment.

Download the template and PowerShell helper from here.

Assume you need Windows 10 Anniversary edition PowerShell versions for these client/deployment actions.

Open a PowerShell admin prompt in the download location, and run [.\deploy.ps1].

You will be prompted for your Azure login, a resource group and location (e.g. “uksouth”), and an admin password for the VM.

If all goes fine, then you will be able to rdp to the VM, and be able to start up SSMS.

Finally, a couple of pictures I took to focus the mind when trying to reduce the template to the bare minimum to get a working VM:

The next day… in fact I have started to remove the literals as I get more familiar. Again, I refer you the MS Azure docs above.

Azure ARM: listing the images available to your subscription

I need to identify the images that are available to my subscription. For example, if I want an image that gives me SQL Server 2016, short of Googling, how do I find that?

I seem to remember that this was kind of easy in the Classic Azure deployment model, but I am now using Azure Resource Manager (ARM), and I don’t wish to return to Classic, i.e. legacy, which is not where the development effort is being invested.

For my use-case, I need to inject the answer (identifying the available images) into a ARM deployment template, but I think it applies to any use-case where you need to identify the images that are available to your subscription.

These are the parts of the template that I need to populate with the answer, namely Publisher (most significant part of the sort), Offer, and Sku. Right now their default values are those in blue in the json extract.

"imagePublisher": {
 "type": "string",
 "defaultValue": "MicrosoftWindowsServer",
 "metadata": {
 "description": "Image Publisher"

"imageOffer": {
 "type": "string",
 "defaultValue": "WindowsServer",
 "metadata": {
 "description": "Image Offer"

"imageSKU": {
 "type": "string",
 "defaultValue": "2012-R2-Datacenter",
 "metadata": {
 "description": "Image SKU"

But as said I want a set that gives me some flavour of SQLServer 2016. Getting the right values is not as simple as running a built-in Azure PowerShell function. Oh no. There are some hoops to go through.

Once you have logged into your subscription, these are the steps:

1. Find the publisher. But how do I know which is the publisher I need? For me that is quite easy as it is usually some variation on Microsoft. But using the Out-GridView PS function will help.  I also need to specify a location. So we can start with this:

Get-AzureRmVMImagePublisher -Location uksouth | Out-GridView

Looking at the result of that below, after playing with the search filter, then I see my likely Publisher is [MicrosoftSQLServer].

So I can refine my query to this and stick the object output in a variable:

$publisher = Get-AzureRmVMImagePublisher -Location uksouth | ? {$_.PublisherName -like "*microsoftsql*"}

2. Find the offer.

Get-AzureRmVMImageOffer -Location "uksouth" -PublisherName $publisher.PublisherName

3. Find the SKU

Now I have my likely offer (SQL2016SP1-WS2016), my publisher (MicrosoftSQLServer), and now I need the sku:

Get-AzureRmVMImageSku -Location "uksouth" -PublisherName "MicrosoftSQLServer"  -Offer "SQL2016SP1-WS2016"

With those 3 answers (plus the location, which also comes into play), I can update the json:

The steps to deploy the template will be another post, but right now, as I chose Express, this is what I see in the created VM:


Microsoft SQL Server 2016 (SP1) (KB3182545) - 13.0.4001.0 (X64)   Oct 28 2016 18:17:30   Copyright (c) Microsoft Corporation  Express Edition (64-bit) on Windows Server 2016 Datacenter 6.3 <X64> (Build 14393: ) (Hypervisor)

Azure and PowerShell: getting the status of the VM

If you run this, then you get a bunch of information… but not the key points about provisioning status:


$vmStatus = Get-AzureRmVM | Where-Object { $_.Name -eq "myvm1"} 
Write-Host $vmStatus.DataDiskNames 
Write-Host $vmStatus.DiagnosticsProfile 
Write-Host $vmStatus.HardwareProfile 
Write-Host $vmStatus.HardwareProfile.VmSize 
Write-Host $vmStatus.StatusCode 
Write-Host $vmStatus.ResourceGroupName 
Write-Host $vmStatus.Location 
Write-Host $vmStatus.HardwareProfile.VmSize 
Write-Host $vmStatus.StorageProfile.ImageReference.Sku 
Write-Host $vmStatus.StorageProfile.OsDisk.OsType 
Write-Host $vmStatus.StorageProfile.OsDisk.Name 
Write-Host $vmStatus.StorageProfile.OsDisk.Vhd.Uri

So the same command, but now specifying the resource name and vm name as arguments, gives this:

$vmStatus = Get-AzureRmVM -ResourceGroupName $rgName -Name $vmName -Status


And from there, we can drill in. For example:


That was a VM that is deallocated. This is how a running VM looks: