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…
Pre-Requisites
Before we get into the actual script please make sure you have the correct Powershell Modules on your Machine by following Microsoft guide here: https://docs.microsoft.com/en-us/powershell/azure/install-azurerm-ps?view=azurermps-5.5.0
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:

Log on to your Azure Account
#Connect to subscription
Login-AzureRmAccount
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: http://www.florisvanderploeg.com/available-vm-sizes-and-images-in-azure-per-location/
VM Sizes Available based on Location, my script requires you to populate $vmsize with the Name variable you would like:

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:

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:

These parameters are then used in the following line to create the VM you have specified:
Parameters
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.
Try-Catch
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:
-Location $location-SubnetId $subnetID.Id -PrivateIpAddress $privateIP -PublicIpAddressId $publicIP.Id
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.
Summary
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
Cheers,
Nicola