Working with images in Azure PowerShell

Learn how to work with images in PowerShell in this article by Thomas Mitchell, a 25+ year veteran of the IT industry with an in-depth skill set that spans numerous IT disciplines.

Welcome to Working with Images!  We’re going to take a look at some image-centric tasks and commands that you should know how to handle as part of your day-to-day operations. This article will help you to deploy virtual machines from images in the Marketplace and also how to deploy virtual machines with custom images.

Working with Marketplace Images

Although a virtual machine can be deployed in Azure with default options, the Azure marketplace offers numerous virtual machine images that can be used to create a new virtual machine.

You need to deploy a virtual machine, called MyVM, using the default Windows Server 2016-Datacenter image. Here, you’ll learn how to use PowerShell to search the marketplace for other Windows images and how to deploy a new virtual machine in Azure using one of those images.

Creating a resource group

Before deploying a VM in Azure with PowerShell, you need to first create a resource group into which the VM will be deployed. An Azure resource group, by the way, is a logical container into which Azure resources are deployed and from where they are managed. Deploying a resource group is rather easy; it is completed with just a single PowerShell command.

To provision a group, you just need to run the New-AzureRMResourceGroup command. When running the command, you need to specify a name for the resource group and a location for it:

New-AzureRmResourceGroup -ResourceGroupName "VMLab" -Location "EastUS"

The preceding command creates a resource group called VMLab and it creates it in the EastUS location:

Running the New-AzureRMResourceGroup command takes just a moment or two and, once the command completes, you can visit the Azure dashboard to confirm that the resource group has been created. Instead, you can run the Get-AzureRmResourceGroup PowerShell command without any switches, to ensure that the new resource group is listed.

To confirm that your new VMLab resource group has been created, run the following command:

Get-AzureRmResourceGroup

Upon running the preceding command, you should see a resource group called VMLab listed. 

Key PowerShell commands

The process of deploying a virtual machine using a specific image includes finding a publisher, finding an offer from that publisher, and then locating an SKUfor the image to use.

To work through this process, you need to run three different PowerShell commands:

  • Get-AzureRmVMImagePublisher: This command returns a list of image publishers.
  • Get-AzureRmVMImageOffer: This command returns a list of image offers from a specific publisher.
  • Get-AzureRmVMImageSku: This command will filter on the publisher and offer name to return a list of available image names.

The process seems, on the surface, a bit unwieldy, but it’s not terribly difficult. Once you’ve done it a few times, it really doesbecome second nature:

  1. To track down an image to deploy from, launch a PowerShell session, connect to the Azure tenant, and use the following commands, starting with the Get-AzureRmVMImagePublisher command:
      Get-AzureRmVMImagePublisher -Location "EastUS"

As you can see in the following screenshot, the preceding command returns a list of publishers available in the EastUS location. If you are following along, make sure MicrosoftWindowsServer is listed, since this is the publisher that provides Windows OS images on the marketplace. The following screenshot shows all publishers in the EastUS location:

  • After ensuring that MicrosoftWindowsServer is listed, run the Get-AzureRmVMImageOffer command to see what image offers are available in the EastUS location from the MicrosoftWindowsServer publisher:
      Get-AzureRmVMImageOffer `
       -Location "EastUS" `
       -PublisherName MicrosoftWindowsServer

There are three MicrosoftWindowsServer offers available in EastUS. To deploy a Windows virtual machine, you’ll want to ensure WindowsServer is one of the choices available. The following screenshot shows the available image offers from the MicrosoftWindowsServer publisher in the EastUS location:

  • Track down available image names within the WindowsServer offer, using the Get-AzureRmVMImageSKU command:
      Get-AzureRmVMImageSku `
       -Location "EastUS" `
       -PublisherName "MicrosoftWindowsServer" `
       -Offer "WindowsServer"

Running the preceding command returns quite a few options. Keep in mind that the list you see (if you are following along) is filtered, based on the specified Publisher and Image Offer. For this exercise, you’ll want to ultimately choose the 2016-Datacenter option—since that is the OS we are going to deploy in this exercise. In the following screenshot, you can see the many different SKUs that are available through the WindowsServer offer from the MicrosoftWindowsServer publisher:

Now that you know which publisher you are using, which offer you will need, and which image you are going to deploy from, you can deploy a virtual machine using your chosen image.

Provisioning a new virtual machine from a specific image

In the previous section, we decided we would use the 2016-Datacenter image for a new virtual machine. In this section, I am going to explain how to deploy a virtual machine based on the 2016-Datacenter image, within the WindowsServer offer, from the  MicrosoftWindowsServer publisher.

To deploy the new virtual machine, which we are going to call myVM2, you need to first capture some credentials to use as the local admin for the new virtual machine. To specify the local admin credentials for the new virtual machine, run the following command:

$cred = Get-Credential

To deploy a new virtual machine (called myVM2), using the preceding information, run the New-AzureRmVm command in a PowerShell session that’s been connected to your Azure tenant:

New-AzureRmVm `
 -ResourceGroupName "VMLab" `
 -Name "myVM2" `
 -Location "EastUS" `
 -VirtualNetworkName "myVnet" `
 -SubnetName "mySubnet" `
 -SecurityGroupName "myNSG" `
 -PublicIpAddressName "myPublicIpAddress2" `
 -ImageName "MicrosoftWindowsServer:WindowsServer:2016-Datacenter:latest" `
 -Credential $cred `
 -AsJob

The ImageName switch specifies the value returned by the Get-AzureRmVMImageSku command in the previous section. This is the switch that tells Azure what specific image to deploy the new virtual machine from.

The AsJob switch creates the virtual machine as a background task and returns control of the PowerShell prompt to you, so you can continue working without needing to wait for the previous command to complete.

Since this command is deploying a virtual machine, it can take a while to complete. After a few minutes (usually 15 minutes or so), the new myVM2 virtual machine will be deployed:

Before continuing you can run the following Get-AzureRmVm command and confirm that the myVM2 virtual machine is deployed and running:

Get-AzureRmVm -ResourceGroupName VMLab -Name MyVM2 -status

Assuming you did everything right, you will be able to see the following output, indicating that the new myVM2virtual machine has been deployed and is running:

Using custom images

Sometimes, though, a default or marketplace image just isn’t sufficient for a virtual machine’s deployment. An example of this in the real world would be a case where several virtual machines with a particular application installed are needed. Another example would be a case where a gold image server image is maintained so that when a virtual machine is deployed from it, the server that gets deployed is already fully patched, negating the need to spend hours patching it up to date.

Enter Custom Images

Custom images are essentially the same as images available onthe marketplace. However, custom images are created by you. By using custom images, you can deploy preconfigured servers, saving yourself hours of post-deployment configuration.

In this section, we will create a custom image of an Azure virtual machine and use it to deploy a customized virtual machine.

You will learn how to do the following:

  • Sysprep and generalize a virtual machine
  • Create a custom image from an existing virtual machine
  • Create a new virtual machine from a custom image
  • List all the images in an Azure subscription
  • Delete an image

Before you begin

Throughout the rest of this exercise, I’m going to walk you through the steps required to take an existing virtual machine, create a custom image from it, and then use that image to deploy a new customized virtual machine based on the image. To follow along with this exercise, you need to have an existing Windows 2016 virtual machine, called myVM2, in Azure to work with. It should be deployed to a resource group called VMLab

Preparing a virtual machine

The first step in deploying a virtual machine based on a custom image is to prepare the source virtual machine. Creating an image from a source virtual machine requires the source virtual machine to be generalized and deallocated. Once this has been completed, the source virtual machine needs to be marked as generalized in Azure. Only after these tasks have been completed can an image be made from the virtual machine.

Using sysprep

Sysprep is the tool that’s used to generalize the source virtual machine. It is a Windows utility that essentially removes all account information from a machine. What this tool does is remove security information, such as the SID/GUID, from a virtual machine and then it prepares the computer for a first-time boot— much like a new laptop would behave upon the initial boot. 

Removing all security information from a virtual machine allows an image of it to be taken and used over and over without duplicate SIDs/GUIDs causing issues related to having multiple identical computers on the network.

To begin the process of preparing the myVM2 virtual machine to be used as an image, perform the following steps:

  1. Log in to the virtual machine using RDP and launch the Command Prompt as an administrator. Get the public IP for the virtual machine so you can RDP to it by running the following command:
      Get-AzureRmPublicIpAddress `
       -Name myPublicIPaddress2 `
       -ResourceGroupName VMLab | Select IPAddress
  • Once you’ve logged into myVM2, launch the command prompt as an admin and change to the %windir%\system32\sysprep directory and run sysprep.exe:
  • From the System Preparation Tooldialog box, choose Enter System Out-of-Box Experience(OOBE) and make sure that the Generalize checkbox is checked. In Shutdown Options, select Shutdown and then click OK:
  • Clicking Oklaunches the Sysprep process. When Sysprep completes, the virtual machine is automatically shut down.Do not restart the virtual machine!

Deallocating and generalizing

Before creating an image from the source virtual machine, the virtual machine must first be deallocated and marked as generalized in Azure:

  1. Confirm the myVM2 virtual machine has been shut down by running the Get-AzureRmVm command:
      Get-AzureRmVm -Name MyVM2 -ResourceGroupName VMLab -status
  • Stop and deallocate the virtual machine by running the following command:
     Stop-AzureRmVm -ResourceGroupName VMLab -Name myVM2 -Force
  • Run the Get-AzureRmVm command to be sure the virtual machine is stopped and deallocated:
      Get-AzureRmVm -Name MyVM2 -ResourceGroupName VMLab -status
  • Once the virtual machine has stopped and shows deallocated when you run Get-AzureRmVm, set its status to generalized using the Set-AzureRmVm command:
      Set-AzureRmVM -ResourceGroupName VMLab -Name myVM2 -Generalized
  • Running the preceding command deallocates the source virtual machine and marks it as generalized, preparing it for the imaging process. Confirm that the machine is generalized by running the Get-AzureRmVm command: 
      Get-AzureRmVm -Name MyVM2 -ResourceGroupName VMLab -status

You should see VM generalized as one of the statuses listed.

Creating an image

With the source virtual machine (myVM2) generalized and deallocated, it can now be used to generate an image. Creating an image requires the use of two different PowerShell commands: New-AzureRmImageConfig and New-AzureRmImage.

To create an image from myVM2, three things need to happen. First, the myVM2 virtual machine config needs to be loaded into a variable. Second, the image configuration needs to be created from myVM2. And third, the actual image needs to be created.

Follow these instructions to complete the necessary steps.

Retrieving the source VM

Run the following command to retrieve the source myVM2 info and store it in a variable:

$vm = Get-AzureRmVM -Name myVM2 -ResourceGroupName VMLab

This command will not generate any feedback on the screen, since all it’s doing is loading info into a variable.

Creating an image configuration

Run the New-AzureRmImageConfig command to create an image configuration that will be used to create the eventual image:

$image = New-AzureRmImageConfig `
-Location EastUS `
-SourceVirtualMachineId $vm.ID

Creating an image

The last step in image creation is the actual creation of the image from the image configuration. Run the New-AzureRmImage command to create the actual image:

New-AzureRmImage `
-Image $image `
-ImageName myImage `
-ResourceGroupName VMLab

Upon completion of the preceding steps, you are left with a new image, called myImage. The following screenshot shows the new image that was successfully created:

This image, based on the myVM2 virtual machine, can be used to deploy additional virtual machines that will be configured identically to myVM2.

Creating a VM from an image

Once an image has been created, it can be used to provision additional virtual machines. Creating a new virtual machine in Azure from a custom image isn’t terribly different than creating a virtual machine using a typical Marketplace image.

When you deploy an Azure virtual machine from a Marketplace image, you must provide information about the image publisher, the offer, the SKU, and the version.

Using a basic set of parameters (switches) for the New-AzureRmVm command allows you to just provide the name of the custom image (if it is in the same resource group as the virtual machine you are deploying).

The following New-AzureRmVm command will provision a new virtual machine in Azure, called myVM3, using the image called myImage. Run the command to create a new virtual machine, called MyVM3:

New-AzureRmVm `
-ResourceGroupName "VMLab" `
-Name "myVM3" `
-ImageName "myImage" `
-Location "EastUS" `
-VirtualNetworkName "myVnet" `
-SubnetName "mySubnet" `
-SecurityGroupName "myNSG" `
-PublicIpAddressName "myPublicIP3"

Because you didn’t create local admin credentials before running the preceding command, you will be prompted to create local admin credentials. Once you supply them, the new myVM3 virtual machine will be provisioned. Running the New-AzureRmVm command should produce output similar to what you see here: 

Once the preceding command completes, run the following command to retrieve the public IP for myVM3 and use it to RDP into the new virtual machine and confirm it functions as expected:

Get-AzureRmPublicIpAddress `
-Name myPublicIP3 `
-ResourceGroupName VMLab | Select IPAddress

Managing images

Deploying a new virtual machine from an image is all well and good. However, it helps to know how to perform some basic image-management tasks as well. You can use the following instructions to perform some common image-management tasks via PowerShell.

Listing images by name

The following command enables you to list all available images by name:

Find-AzureRmResource -ResourceType Microsoft.Compute/images

Deleting an Image

The following command deletes the myImage image from the VMLab resource group:

Remove-AzureRmImage -ImageName myImage -ResourceGroupName VMLab

Don’t worry, deleting the image won’t break the virtual machine that you deployed from it. The image just won’t be available to create any more VMs:

Congratulations! You’ve now learned how to create a disk image from an existing virtual machine and then use that image to deploy a new virtual machine—all with PowerShell!

If you found this article interesting, you can explore Azure PowerShell Quick Start Guideto leverage PowerShell to perform many day-to-day tasks in Microsoft Azure. Taking you through the basic tasks of installing Azure PowerShell and connecting to Azure, Azure PowerShell Quick Start Guidewill help you learn to properly connect to an Azure tenant with PowerShell.

Leave A Reply

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

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