Upload a generalized VHD to Azure to create a new VM

This topic covers uploading a generalized unmanaged disk to a storage account and then creating a new VM using the uploaded disk. A generalized VHD image has had all of your personal account information removed using Sysprep.

If you want to create a VM from a specialized VHD in a storage account, see Create a VM from a specialized VHD.

This topic covers using storage accounts, but we recommend customers move to using Managed Disks instead. For a complete walk-through of how to prepare, upload and create a new VM using managed disks, see Create a new VM from a generalized VHD uploaded to Azure using Managed Disks.

Prepare the VM

A generalized VHD has had all of your personal account information removed using Sysprep. If you intend to use the VHD as an image to create new VMs from, you should:

Generalize a Windows virtual machine using Sysprep

This section shows you how to generalize your Windows virtual machine for use as an image. Sysprep removes all your personal account information, among other things, and prepares the machine to be used as an image. For details about Sysprep, see How to Use Sysprep: An Introduction.

Make sure the server roles running on the machine are supported by Sysprep. For more information, see Sysprep Support for Server Roles

Important

If you are running Sysprep before uploading your VHD to Azure for the first time, make sure you have prepared your VM before running Sysprep.

  1. Sign in to the Windows virtual machine.
  2. Open the Command Prompt window as an administrator. Change the directory to %windir%\system32\sysprep, and then run sysprep.exe.
  3. In the System Preparation Tool dialog box, select Enter System Out-of-Box Experience (OOBE), and make sure that the Generalize check box is selected.
  4. In Shutdown Options, select Shutdown.
  5. Click OK.

    Start Sysprep

  6. When Sysprep completes, it shuts down the virtual machine.

Important

Do not restart the VM until you are done uploading the VHD to Azure or creating an image from the VM. If the VM accidentally gets restarted, run Sysprep to generalize it again.

Upload the VHD

Upload the VHD to an Azure storage account.

Log in to Azure

If you don't already have PowerShell version 1.4 or above installed, read How to install and configure Azure PowerShell.

  1. Open Azure PowerShell and sign in to your Azure account. A pop-up window opens for you to enter your Azure account credentials.

    Connect-AzureRmAccount
    
  2. Get the subscription IDs for your available subscriptions.

    Get-AzureRmSubscription
    
  3. Set the correct subscription using the subscription ID. Replace <subscriptionID> with the ID of the correct subscription.

    Select-AzureRmSubscription -SubscriptionId "<subscriptionID>"
    

Get the storage account

You need a storage account in Azure to store the uploaded VM image. You can either use an existing storage account or create a new one.

To show the available storage accounts, type:

Get-AzureRmStorageAccount

If you want to use an existing storage account, proceed to the Upload the VM image section.

If you need to create a storage account, follow these steps:

  1. You need the name of the resource group where the storage account should be created. To find out all the resource groups that are in your subscription, type:

    Get-AzureRmResourceGroup
    

    To create a resource group named myResourceGroup in the West US region, type:

    New-AzureRmResourceGroup -Name myResourceGroup -Location "West US"
    
  2. Create a storage account named mystorageaccount in this resource group by using the New-AzureRmStorageAccount cmdlet:

    New-AzureRmStorageAccount -ResourceGroupName myResourceGroup -Name mystorageaccount -Location "West US" `
        -SkuName "Standard_LRS" -Kind "Storage"
    

Start the upload

Use the Add-AzureRmVhd cmdlet to upload the image to a container in your storage account. This example uploads the file myVHD.vhd from "C:\Users\Public\Documents\Virtual hard disks\" to a storage account named mystorageaccount in the myResourceGroup resource group. The file will be placed into the container named mycontainer and the new file name will be myUploadedVHD.vhd.

$rgName = "myResourceGroup"
$urlOfUploadedImageVhd = "https://mystorageaccount.blob.core.windows.net/mycontainer/myUploadedVHD.vhd"
Add-AzureRmVhd -ResourceGroupName $rgName -Destination $urlOfUploadedImageVhd `
    -LocalFilePath "C:\Users\Public\Documents\Virtual hard disks\myVHD.vhd"

If successful, you get a response that looks similar to this:

MD5 hash is being calculated for the file C:\Users\Public\Documents\Virtual hard disks\myVHD.vhd.
MD5 hash calculation is completed.
Elapsed time for the operation: 00:03:35
Creating new page blob of size 53687091712...
Elapsed time for upload: 01:12:49

LocalFilePath           DestinationUri
-------------           --------------
C:\Users\Public\Doc...  https://mystorageaccount.blob.core.windows.net/mycontainer/myUploadedVHD.vhd

Depending on your network connection and the size of your VHD file, this command may take a while to complete.

Create a new VM

You can now use the uploaded VHD to create a new VM.

Set the URI of the VHD

The URI for the VHD to use is in the format: https://mystorageaccount.blob.core.windows.net/mycontainer/MyVhdName.vhd. In this example the VHD named myVHD is in the storage account mystorageaccount in the container mycontainer.

$imageURI = "https://mystorageaccount.blob.core.windows.net/mycontainer/myVhd.vhd"

Create a virtual network

Create the vNet and subnet of the virtual network.

  1. Create the subnet. The following sample creates a subnet named mySubnet in the resource group myResourceGroup with the address prefix of 10.0.0.0/24.

    $rgName = "myResourceGroup"
    $subnetName = "mySubnet"
    $singleSubnet = New-AzureRmVirtualNetworkSubnetConfig -Name $subnetName -AddressPrefix 10.0.0.0/24
    
  2. Create the virtual network. The following sample creates a virtual network named myVnet in the West US location with the address prefix of 10.0.0.0/16.

    $location = "West US"
    $vnetName = "myVnet"
    $vnet = New-AzureRmVirtualNetwork -Name $vnetName -ResourceGroupName $rgName -Location $location `
        -AddressPrefix 10.0.0.0/16 -Subnet $singleSubnet
    

Create a public IP address and network interface

To enable communication with the virtual machine in the virtual network, you need a public IP address and a network interface.

  1. Create a public IP address. This example creates a public IP address named myPip.

    $ipName = "myPip"
    $pip = New-AzureRmPublicIpAddress -Name $ipName -ResourceGroupName $rgName -Location $location `
        -AllocationMethod Dynamic
    
  2. Create the NIC. This example creates a NIC named myNic.

    $nicName = "myNic"
    $nic = New-AzureRmNetworkInterface -Name $nicName -ResourceGroupName $rgName -Location $location `
        -SubnetId $vnet.Subnets[0].Id -PublicIpAddressId $pip.Id
    

Create the network security group and an RDP rule

To be able to log in to your VM using RDP, you need to have a security rule that allows RDP access on port 3389.

This example creates an NSG named myNsg that contains a rule called myRdpRule that allows RDP traffic over port 3389. For more information about NSGs, see Opening ports to a VM in Azure using PowerShell.

$nsgName = "myNsg"

$rdpRule = New-AzureRmNetworkSecurityRuleConfig -Name myRdpRule -Description "Allow RDP" `
    -Access Allow -Protocol Tcp -Direction Inbound -Priority 110 `
    -SourceAddressPrefix Internet -SourcePortRange * `
    -DestinationAddressPrefix * -DestinationPortRange 3389

$nsg = New-AzureRmNetworkSecurityGroup -ResourceGroupName $rgName -Location $location `
    -Name $nsgName -SecurityRules $rdpRule

Create a variable for the virtual network

Create a variable for the completed virtual network.

$vnet = Get-AzureRmVirtualNetwork -ResourceGroupName $rgName -Name $vnetName

Create the VM

The following PowerShell script shows how to set up the virtual machine configurations and use the uploaded VM image as the source for the new installation.

# Enter a new user name and password to use as the local administrator account 
    # for remotely accessing the VM.
    $cred = Get-Credential

    # Name of the storage account where the VHD is located. This example sets the 
    # storage account name as "myStorageAccount"
    $storageAccName = "myStorageAccount"

    # Name of the virtual machine. This example sets the VM name as "myVM".
    $vmName = "myVM"

    # Size of the virtual machine. This example creates "Standard_D2_v2" sized VM. 
    # See the VM sizes documentation for more information: 
    # https://azure.microsoft.com/documentation/articles/virtual-machines-windows-sizes/
    $vmSize = "Standard_D2_v2"

    # Computer name for the VM. This examples sets the computer name as "myComputer".
    $computerName = "myComputer"

    # Name of the disk that holds the OS. This example sets the 
    # OS disk name as "myOsDisk"
    $osDiskName = "myOsDisk"

    # Assign a SKU name. This example sets the SKU name as "Standard_LRS"
    # Valid values for -SkuName are: Standard_LRS - locally redundant storage, Standard_ZRS - zone redundant
    # storage, Standard_GRS - geo redundant storage, Standard_RAGRS - read access geo redundant storage,
    # Premium_LRS - premium locally redundant storage. 
    $skuName = "Standard_LRS"

    # Get the storage account where the uploaded image is stored
    $storageAcc = Get-AzureRmStorageAccount -ResourceGroupName $rgName -AccountName $storageAccName

    # Set the VM name and size
    $vmConfig = New-AzureRmVMConfig -VMName $vmName -VMSize $vmSize

    #Set the Windows operating system configuration and add the NIC
    $vm = Set-AzureRmVMOperatingSystem -VM $vmConfig -Windows -ComputerName $computerName `
        -Credential $cred -ProvisionVMAgent -EnableAutoUpdate
    $vm = Add-AzureRmVMNetworkInterface -VM $vm -Id $nic.Id

    # Create the OS disk URI
    $osDiskUri = '{0}vhds/{1}-{2}.vhd' `
        -f $storageAcc.PrimaryEndpoints.Blob.ToString(), $vmName.ToLower(), $osDiskName

    # Configure the OS disk to be created from the existing VHD image (-CreateOption fromImage).
    $vm = Set-AzureRmVMOSDisk -VM $vm -Name $osDiskName -VhdUri $osDiskUri `
        -CreateOption fromImage -SourceImageUri $imageURI -Windows

    # Create the new VM
    New-AzureRmVM -ResourceGroupName $rgName -Location $location -VM $vm

Verify that the VM was created

When complete, you should see the newly created VM in the Azure portal under Browse > Virtual machines, or by using the following PowerShell commands:

    $vmList = Get-AzureRmVM -ResourceGroupName $rgName
    $vmList.Name

Next steps

To manage your new virtual machine with Azure PowerShell, see Manage virtual machines using Azure Resource Manager and PowerShell.