In this article, I will be showing you how to create an Azure VM from scratch with the Azure Resource Manager (ARM) PowerShell cmdlets.

Adam Bertram

Adam Bertram is a 20-year IT veteran, Microsoft MVP, blogger, and trainer. Adam is the founder of the e-learning tech screencast platform TechSnips. Catch up on Adam’s articles at, or follow TechSnips on Twitter at @techsnips_io.

When you build an IaaS Microsoft Azure virtual machine with PowerShell, you have three options at this time:

  1. Azure Service Management (classic)
  2. Azure Resource Manager (ARM)
  3. Azure Resource Manager (ARM) templates

Today, I will cover option #2. To demonstrate this, I’ll be building a VM from a Windows Server 2012 R2 image from the ground up with absolutely no Azure infrastructure set up already. I’ll be doing this to show you the many dependencies that an Azure VM has that you might have to create as a part of this process as well.

If this is the first time you’re building an Azure VM from scratch with PowerShell, it might seem a little scary. After all, you might have to use up to 13 different cmdlets, depending on your existing Azure infrastructure, to get one of these up and running. In this article, I’ll basically be building the infrastructure along with it. If you already have entities such as a resource group, virtual networks, and a storage account set up, the process will be much shorter.

This article is not meant to be an in-depth overview of how to build Azure VMs with ARM but rather what is necessary to get your first VM created with ARM and PowerShell. I will cover all dependencies that an Azure VM has and show you how to build each entity. Due to the length that this article would be if I explained each step in detail, I’ve chosen to only give you the minimum configuration you need to get an Azure VM running with ARM without much description. Use this article as a code guide to get an understanding of which objects are required to build an Azure VM with ARM.

Before you can go anywhere, you’ll first need to get the Azure PowerShell module installed. This includes the Azure.RM module we’ll be using in this article. Next, you have to log on to Azure with Login-AzureRmAccount.

The very top-most dependency for a VM is a resource group. Every VM created with ARM has to be in a resource group. To create a resource group, we’ll use the New-AzureRmResourceGroup cmdlet. I’ll create my resource in the West US Azure region.

Next, I’ll need to create a subnet for the VM to reside on the network. I’ll put my VM on the network when it gets built.

I’ll create my virtual network by specifying the subnet I’d like to use with it, as well as which resource group and location to place it in.

We’ll need somewhere to store the blob that the VM will be a part of, so we’ll need to create a storage account.

Next, we’ll need a public IP address to assign to the VM.

We have to create a NIC for the VM.

We now need to create a VM configuration to specify the name of the VM and the size you’d like to have it provisioned at.

Next, we need to create the OS itself. Here, we’ll specify various OS-specific attributes.

We need to pick what image our OS will come from. Here, I’m picking Windows Server 2012 R2 Datacenter with the latest patches.

Next, we’ll attach the NIC we built earlier.

We’ll build the disk that the OS will be stored on. We’ll store it in the storage account we built earlier inside of a storage container called vhds.

To create the VM, you need this command:

After the VM is built, be aware that Microsoft will begin charging your subscription a nominal usage fee. When you are just learning, always remember to stop the VM when you’re done. Use the Stop-AzureVM cmdlet to do this.

You can see there’s a lot to building a single VM if you don’t have any of the infrastructure built already. However, chances are you probably already have a lot of the components pre-built that your VM can use. If this is the case, simply skip over that section of code and continue on. If you are just starting to test out Azure, though, this article will be a great start for beginning to provision Azure VMs with ARM and PowerShell.

Join the 4sysops PowerShell group!

  1. Rustem Gumbeev 4 years ago

    Great article!

    May be you can help me with my problem?

    I am creating an environment using ARM now. The thing I need is several VNETs and an ExpressRoute curcuit. All VNETs should communicate with each other, but only some of them should be linked to ER curcuit.

    In Classic it was possible to coexist ExpressRoute link and Site-to-Site connection for the VNET (though this required manual editing of the XML file). Is there a way to do that in ARM using PowerShell?

    May be there is a better way to reach the result I described?


  2. IamJohnny45 3 years ago

    Isn't this example missing the most important part which is to actually create the VM?



    • Author
      Adam Bertram 3 years ago

      Yep. You're right! I got all the way to the end and missed the best part!


      New-AzureRmVM -VM $vm -ResourceGroupName MyResourceGroup -Location 'West US'


  3. Satish 3 years ago

    Great write up Adam! Thanks for taking the time to put it together.



  4. Peter Monadjemi 3 years ago

    The variable $vmName is used but not assigned. I am using $Vm.Name instead:

    $OSDiskUri = $StorageAccount.PrimaryEndpoints.Blob.ToString() + "vhds/" + $VM.Name + $OSDiskName + ".vhd"
    I also get this error at the end:

    New-AzureRmVM : The value of parameter imageReference.version is invalid.
    StatusCode: 400
    ReasonPhrase: Bad Request





  5. subhash 2 years ago

    Hi Adam,

    I am Getting below error. Could you please suggest

    PS C:\WINDOWS\system32> New-AzureRmVM -VM $vm -ResourceGroupName MyResourceGroup1 -Location 'WestIndia'
    New-AzureRmVM : The value of parameter imageReference.offer is invalid.
    ErrorCode: InvalidParameter
    ErrorMessage: The value of parameter imageReference.offer is invalid.
    StatusCode: 400
    ReasonPhrase: Bad Request
    OperationID : 4263f7aa-332b-4f0f-bd34-43ff34da2ae4
    At line:1 char:1
    + New-AzureRmVM -VM $vm -ResourceGroupName MyResourceGroup1 -Location ' ...
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : CloseError: (:) [New-AzureRmVM], ComputeCloudException
    + FullyQualifiedErrorId : Microsoft.Azure.Commands.Compute.NewAzureVMCommand


Leave a reply

Your email address will not be published. Required fields are marked *


© 4sysops 2006 - 2019


Please ask IT administration questions in the forums. Any other messages are welcome.


Log in with your credentials


Forgot your details?

Create Account