< Back

Azure: Create a VM from a Snapshot using GUI Powershell script

Tue Sep 17, 2019 10:29 am

This script gives you a GUI list where you can select options to restore or create a VM from a saved snapshot in Azure. It is easier to use a GUI when creating only a few VM's from your saved snapshot. If you need to create a lot of VM's it would be easier to use data from a .csv file to automate the process. On the other hand if you have specific fixed names and values for your VM it is better to code in your values in the script.



I have been using a windows 10 VM on Azure when required and usually archive it as a snapshot once the task is done. When required I restore it from the snapshot and continue with any new tasks. I do not need to keep this running continuously and pay the additional costs. To make it easier I have setup a script to recreate a VM from the snapshot. I am able to select the VM size when recreating it depending on the requirements for the task at hand. Here is the script to Create a VM from a Snapshot. This can be used along with scripts to Create a snapshot , Delete an Azure VM with its associated resources to manage your developer VM instances.

    This one will be useful as a generic simple interface to get your task done easily. I have setup the script to prompt for only the minimum input required and retrieve most values automatically.

    Here are few screenshots of the GUI:

    Enter VM name

    Image



    Select VM size

    Image



    Completed: Once completed you would get a prompt in a few minutes.

    Image



    You would need the Azure powershell module to run the code , if not present you can run powershell as administrator and install the modules before running the script.

    Code: Select all

    Install-Module -Name AzureRM -AllowClobber


    Since this script uses Forms you wont be able to run this in Azure Cloud shell , this can be run from your Windows machine.



    For creating the Selection List and Input box GUI I have used the code available from Selecting Items from a List Box and Creating a Custom Input Box. I have combined these as a function for use in the script.



    You can connect to your Azure account first using the command below:

    Code: Select all

    Connect-AzureRmAccount




    Complete code

    Once connected you can copy and paste the code in your Powershell window to run it.

    Code: Select all

    function Invoke-Inputbox($boxtype, $boxitems, $boxtitle, $boxbutton) {
    Add-Type -AssemblyName System.Windows.Forms
    Add-Type -AssemblyName System.Drawing
    
    $form = New-Object System.Windows.Forms.Form
    $form.Text = $boxtitle
    $form.Size = New-Object System.Drawing.Size(300,200)
    $form.StartPosition = 'CenterScreen'
    
    $OKButton = New-Object System.Windows.Forms.Button
    $OKButton.Location = New-Object System.Drawing.Point(75,120)
    $OKButton.Size = New-Object System.Drawing.Size(75,23)
    $OKButton.Text = $boxbutton
    $OKButton.DialogResult = [System.Windows.Forms.DialogResult]::OK
    $form.AcceptButton = $OKButton
    $form.Controls.Add($OKButton)
    
    $CancelButton = New-Object System.Windows.Forms.Button
    $CancelButton.Location = New-Object System.Drawing.Point(150,120)
    $CancelButton.Size = New-Object System.Drawing.Size(75,23)
    $CancelButton.Text = 'Cancel'
    $CancelButton.DialogResult = [System.Windows.Forms.DialogResult]::Cancel
    $form.CancelButton = $CancelButton
    $form.Controls.Add($CancelButton)
    
    If ($boxtype -eq "input")
    {
    $label = New-Object System.Windows.Forms.Label
    $label.Location = New-Object System.Drawing.Point(10,20)
    $label.Size = New-Object System.Drawing.Size(280,20)
    $label.Text = $boxitems
    $form.Controls.Add($label)
    $textBox = New-Object System.Windows.Forms.TextBox
    $textBox.Location = New-Object System.Drawing.Point(10,40)
    $textBox.Size = New-Object System.Drawing.Size(260,20)
    $form.Controls.Add($textBox)
    
    $form.Topmost = $true
    
    $form.Add_Shown({$textBox.Select()})
    $result = $form.ShowDialog()
    
    if ($result -eq [System.Windows.Forms.DialogResult]::OK)
    {
        $x = $textBox.Text
        return $x
    }
    }
    If ($boxtype -eq "select")
    {
    $listBox = New-Object System.Windows.Forms.ListBox
    $listBox.Location = New-Object System.Drawing.Point(10,40)
    $listBox.Size = New-Object System.Drawing.Size(260,100)
    $listBox.Height = 80
    
    foreach ($Line in $boxitems)
    {
    [void] $listBox.Items.Add($Line)
    }
    
    
    $form.Controls.Add($listBox)
    
    $form.Topmost = $true
    
    $result = $form.ShowDialog()
    
    if ($result -eq [System.Windows.Forms.DialogResult]::OK)
    {
        $x = $listBox.SelectedItem
        return $x
    }
    }
    }
    
    #Provide the subscription Id
    $formlist =(Get-AzureRmSubscription).Name
    $subname = Invoke-Inputbox "select" $formlist "Subscription" "Next"
    $subscriptionId = (Get-AzureRmSubscription  -SubscriptionName $subname).id
    
    #Provide the name of your resource group
    $resgroup = (Get-AzureRmResourceGroup).ResourceGroupName
    $resourceGroupName = Invoke-Inputbox "select" $resgroup "ResourceGroup" "Next"
    
    #Provide the name of the snapshot that will be used to create OS disk
    $snaplist =(Get-AzureRmSnapshot).Name
    $snapshotName =  Invoke-Inputbox "select" $snaplist "Snapshot" "Next"
    
    #Provide the name of an existing virtual network where virtual machine will be created
    $formlist =(Get-AzurermVirtualNetwork).Name
    $virtualNetworkName  = Invoke-Inputbox "select" $formlist "Virtual Network" "Next"
    
    #Provide the name of the virtual machine
    $virtualMachineName = Invoke-Inputbox "input" "VM Name" "Please enter VM name"  "Next"
    
    #Provide the name of the OS disk that will be created using the snapshot
    $osDiskName = $virtualMachineName + "Disk"
    
    #Provide the size of the virtual machine
    #e.g. Standard_DS3
    #Get all the vm sizes in a region using below script:
    #e.g. Get-AzVMSize -Location westus
    $vmnames =(Get-AzurermVMSize -Location westus)
    $vmlist = New-Object string[] $vmnames.length
    for ($i=0; $i -lt $vmnames.length; $i++) 
    {
    $vmlist[$i] = $vmnames.name[$i]+ "("+ $vmnames.memoryinmb[$i]+ ")"+ "("+ $vmnames.numberofcores[$i]+ ")"
    }
    $subname = Invoke-Inputbox "select" $vmlist "VM Size(Memory Size)(Number of Cores)" "Next"
    $virtualMachineSize = $subname.split("(")[0]
    
    #Set the context to the subscription Id where Managed Disk will be created
    Select-AzurermSubscription -SubscriptionId $SubscriptionId
    
    $snapshot = Get-AzurermSnapshot -ResourceGroupName $resourceGroupName -SnapshotName $snapshotName
    
    $diskConfig = New-AzurermDiskConfig -Location $snapshot.Location -SourceResourceId $snapshot.Id -CreateOption Copy
    
    $disk = New-AzurermDisk -Disk $diskConfig -ResourceGroupName $resourceGroupName -DiskName $osDiskName
    
    #Initialize virtual machine configuration
    $VirtualMachine = New-AzurermVMConfig -VMName $virtualMachineName -VMSize $virtualMachineSize
    
    #Use the Managed Disk Resource Id to attach it to the virtual machine. Please change the OS type to linux if OS disk has linux OS
    $VirtualMachine = Set-AzurermVMOSDisk -VM $VirtualMachine -ManagedDiskId $disk.Id -CreateOption Attach -Windows
    
    #Create a public IP for the VM
    $publicIp = New-AzurermPublicIpAddress -Name ($VirtualMachineName.ToLower()+'_ip') -ResourceGroupName $resourceGroupName -Location $snapshot.Location -AllocationMethod Dynamic
    
    #Get the virtual network where virtual machine will be hosted
    $vnet = Get-AzurermVirtualNetwork -Name $virtualNetworkName -ResourceGroupName $resourceGroupName
    
    # Create NIC in the first subnet of the virtual network
    $nic = New-AzurermNetworkInterface -Name ($VirtualMachineName.ToLower()+'_nic') -ResourceGroupName $resourceGroupName -Location $snapshot.Location -SubnetId $vnet.Subnets[0].Id -PublicIpAddressId $publicIp.Id
    
    $VirtualMachine = Add-AzurermVMNetworkInterface -VM $VirtualMachine -Id $nic.Id
    
    #Create the virtual machine with Managed Disk
    $result = (New-AzurermVM -VM $VirtualMachine -ResourceGroupName $resourceGroupName -Location $snapshot.Location).IsSuccessStatusCode
    if ($result) 
    { 
    $Form = New-Object system.Windows.Forms.Form
    $Form.Text = "Script completed!"
    $Label = New-Object System.Windows.Forms.Label
    $Label.Text = "VM created successfully."
    $Label.AutoSize = $True
    $Form.Controls.Add($Label)
    $Form.ShowDialog()
    }
    else 
    { 
    $Form = New-Object system.Windows.Forms.Form
    $Form.Text = "Script completed!"
    $Label = New-Object System.Windows.Forms.Label
    $Label.Text = "VM creation failed."
    $Label.AutoSize = $True
    $Form.Controls.Add($Label)
    $Form.ShowDialog()
    }