This is my personal blog. The opinions and views I express are my own. The information I provide is on an as-is basis. I make no representations as to accuracy, completeness, currentness, suitability, or validity of any information on this blog and will not be liable for any errors, omissions, or delays in this information or any losses, injuries or damages arising from its use.

Automate Creating Lab Virtual Machines in Azure with PowerShell

As you may or may not know, I recently decommissioned my old Dell PowerEdge 1950 server that I used for a few Lab virtual machines. While experimenting with PowerShell on these Virtual Machines, I have found myself in the situation where it would be easier to delete the Virtual Machines and re-create them instead of troubleshooting something I fouled up in the Registry. After the 2nd time rebuilding the lab VMs using the Azure website, I decided to script the process.

The script below will take input from a CSV file and create a virtual machine in your Azure subscription for each row in the CSV file. My example creates 2 virtual machines but you can obviously add as many as you need.

For a production environment in Azure, I would suggest Snapshotting the Virtual Machines. There is a good write-up of the process here: http://www.coreazure.com/snapshot-vms-in-azure-resource-manager/. In my case, for a Lab, snapshots use more storage which costs more $$.


Function New-AzureLab {
    New-AzureLab will create 1 or multiple VMs in Azure based on input parameters from a CSV

    Create a CSV file like below:

    The function will read the input from the CSV file and create VMs in an Azure Resource Group
    .PARAMETER csvpath
    The full path to your CSV file (eg c:\scripts\VMs.csv)

    New-AzureLab -csvpath c:\scripts\VMs.csv
    Imports the applicable values from the CSV file

    1. I already had a Resource Group in Azure therefore I put all the VMs in the same group.
    2. I already had a VM network created, all my VMs are in the same network.

    URLs to related sites
    A good writeup on the process - https://docs.microsoft.com/en-us/azure/virtual-machines/windows/quick-create-powershell
    Azure VM size values - https://docs.microsoft.com/en-us/azure/virtual-machines/windows/sizes-general
    Azure VM Publisher, Offer, SKUs, Version info for various VM types - https://docs.microsoft.com/en-us/azure/virtual-machines/windows/cli-ps-findimage

    CSV file path


    New-AzureLab -csvpath c:\scripts\VMs.csv

        [Parameter(Mandatory=$True,HelpMessage='Enter the Path to your CSV')]
    # Lets make sure the CSV file is actually there
    $testpath = Test-Path -Path $csvpath
    If (!$testpath){
        write-host -ForegroundColor Red '***** Invalid CSV Path *****' -ErrorAction Stop
    } else {

        # This will the be local username and password for each VM
        $Credential = Get-Credential

        # Import the information from my CSV
        Import-Csv -Path "$csvPath" | ForEach-Object {
        # Get the Storage Account Informaiton
        $StorageAccount = Get-AzureRmStorageAccount

        # This is the naming convention for the OS Disk
        $OSDiskName = $_.'VMName' + '_OSDisk'

        # Network Information
        $PublicIP = New-AzureRmPublicIpAddress -Name $_.'InterfaceName' -ResourceGroupName $_.'ResourceGroupName' -Location $_.'Location' -AllocationMethod Dynamic
        $VMNetwork = Get-AzureRmVirtualNetwork
        $Interface = New-AzureRmNetworkInterface -Name $_.'InterfaceName' -ResourceGroupName $_.'ResourceGroupName' -Location $_.'Location' -SubnetId $VMNetwork.Subnets[0].Id -PublicIpAddressId $PublicIP.Id

        ## Setup local VM object
        $VirtualMachine = New-AzureRmVMConfig -VMName $_.'VMName' -VMSize $_.'VMSize'
        $VirtualMachine = Set-AzureRmVMOperatingSystem -VM $VirtualMachine -Windows -ComputerName $_.'ComputerName' -Credential $Credential -ProvisionVMAgent -EnableAutoUpdate
        $VirtualMachine = Set-AzureRmVMSourceImage -VM $VirtualMachine -PublisherName MicrosoftWindowsServer -Offer WindowsServer -Skus 2016-Datacenter -Version 'latest'
        $VirtualMachine = Add-AzureRmVMNetworkInterface -VM $VirtualMachine -Id $Interface.Id
        $OSDiskUri = $StorageAccount.PrimaryEndpoints.Blob.ToString() + 'vhds/' + $OSDiskName + '.vhd'
        $VirtualMachine = Set-AzureRmVMOSDisk -VM $VirtualMachine -Name $OSDiskName -VhdUri $OSDiskUri -CreateOption FromImage

        ## Create the VM in Azure
        New-AzureRmVM -ResourceGroupName $_.'ResourceGroupName' -Location $_.'Location' -VM $VirtualMachine -Verbose



Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.