Azure Basics : Creating a Windows Virtual Machine via Powershell

Note: I originally started writing this script in 2017. Getting back into Azure now I know a lot of the components have changed. I will try to write a version 2.0 on this but thought it would be a good exercise to carry through. 

In another post on this site I walked through how to create a Virtual Machine in Azure Manually. Now after digging about for a bit, I’ve developed the Powershell to do the same. Making life a little easier by only needing to change the variables at the beginning of the script depending on my needs.

This post requires some prior exposure to creating VM’s and Networks in Azure. I have tried to explain at a high level in this post but if there are any further questions please post in the comments section.

I know there are loads of improvements that can still go into this script but it has been a good jumping off point for helping with resource creation and management. I’ve put a copy of the script at the end but will walk through certain parts with an more in depth explanation. Any comments, pointers* and other feedback please let me know.

*ha, obscure C++ joke…I’m here all night…


Before we get into the actual script please make sure you have the correct Powershell Modules on your Machine by following Microsoft guide here:

Use your preferred scripting tool, doing a few lines at a time direct into Powershell to test the water worked best for me before going for the full script. I started out a while back using Powershell ISE but swapped to Visual Studio Code half way through checking the code for this post.

Script Overview

The script discussed will create 1 Windows Virtual Machine to your size and image specifications which will reside on a new (or already existing) Subnet, as part of a larger VNet (also new or existing).

The VM created will have 1 OS Disk and 1 Network Interface Card (NIC). A Storage Account is also created to handle VM Disks. The NIC has a Private Static IP Address that you assign and also a Dynamic Public IP Address. The Dynamic Public IP has been included for quick access to connect into the VM through the Azure Portal once it is built.

Resource Groups are also used to manage the creation of these components one for overall Networking resources and one for the Virtual Machine resources, please see the diagram below for an overview:

Basic diagram
Dotted line marks Resources included in the Virtual Machine Resource Group. VNet and Subnet would reside in separate Network Resource Group


Log on to your Azure Account

#Connect to subscription

Running the above will prompt you to log in to your Azure account, from there we can get into creating new resources and finding out what is available from Azure.

What’s Available?

My script requires you to define various settings as Parameters at the beginning of the script. what VMSize and Image information you would like on the machine you are creating. The following article was extremely helpful, with links to additional scripts that will export .cvs files of what is available in each datacentre location:

VM Sizes Available based on Location, my script requires you to populate $vmsize with the Name variable you would like:

machine sizes
Yellow lines next to potential $vmsize Variables

VM Image and OS options, in the article mentioned above there is a link to a script that will create a Image Availability Matrix which is really helpful. If you pass in the location you are looking to create your resources in it will create a .csv file of all the Image offerings available there. You can then take this information and populate the variables in the script I have created to get the virtual machine you want:

Image Availability Matrix Example (filtered on Offer = Windows AND Sku = Windows-10-N-x64)

In this example we want to create a Windows 10N x64 Virtual Machine, the image from the export above shows the different versions of this image available. However we can transfer this into the script and ask it to always use the “latest” version:

image code
Script Variables Based on Export Information

These parameters are then used in the following line to create the VM you have specified:

$vmConfig=Set-AzureRmVMSourceImage-VM $vmConfig -PublisherName $publisher
-Offer $offer-Skus $skus-Version $version


The script begins with a list of Parameters at the beginning. Once these are all populated you should be able to run the script. As mentioned in the previous section you can populate the image and VM size information from finding the options that suit you.

I have commented next to each option in the script to guide through what is required, but if there are any questions please let me know.


The Try-Catch statements through out the code are to check for the resources that may already exist in your Azure tenant. It does this by checking against the Get- command for the resource in question. If it finds one with the same name it will add to that resource, or if it cannot find it a new resource with the name you have defined will be created.

NIC Creation & IPs

A Network Interface Card (NIC) needs to be added to the VM in order to make it part of the wider network you may wish to create. Revisiting this section of the code I had some issues but managed to work around it by re-declaring the Subnet ID before creating the NIC to pass into its creation with the line below:

$nic=New-AzureRmNetworkInterface-Name $nicName-ResourceGroupName $vmRG

-Location $location-SubnetId $subnetID.Id -PrivateIpAddress $privateIP -PublicIpAddressId $publicIP.Id

The public IP information must be created as a New-AzureRMPublicIpAddress object, for the purposes of this script I’ve just added “publicIP” to the name of the VM as a naming convention:
$publicIP = New-AzureRmPublicIpAddress -Name “$($vmname)_publicIP”
-ResourceGroupName $vmRG -Location $location -AllocationMethod Dynamic
This NIC is then attached to the VM with the following line:
$vmConfig = Add-AzureRmVMNetworkInterface -VM $vmConfig -Id $nic.Id
This now allocates the NIC to the VM you are creating, placing the VM on the Subnet you have defined.

OS Disk and Storage Account

In this script I have only allocated one OSDisk, which i think is created by default in newer versions of Azure Powershell. So Ideally I would like to revisit this part of the script to improve it and add additional disks.

The script ties the disks created to a designated storage account for VM. You can see this in the #OS Disk section of the script.


I hope this has been helpful for anyone else looking into VM creation through Powershell in Azure.

Script to Create a VM based on Variables in Azure




Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s