PowerShell – Automating Server Builds In Azure – Pt. 1 – Basic Builds

During this scripting session, I am working on a system that is running PowerShell 5.0 (February 2015 release).

I started with a very simple goal towards learning Azure and Desired State Configuration: to be able to rapidly deploy a series of machines required for giving demonstrations at user group meetings and internal company discussions.  In order to get my Azure environment to this point, I figured that I would need to learn the following:

  • Build a single deployment using a one-line command.
  • Build a series of constants to provide the one-line command to ensure consistency in my deployments.
  • Build a series of basic parameterized inputs to provide the command the necessary information to deploy the server into a service group for a given purpose (IIS server, print server, etc.)
  • Expand the scope of the script to build a specified number of servers into a service group, or add a number of servers to an existing service group.
  • Build a second command to tear down an environment cleanly when it is no longer required.

Once complete, I will stand up a DSC environment to explore the possibility of leveraging my provisioning scripts to deploy my standardized configurations to a number of different deployments based on the designated purpose.

Before I begin, it should be noted that I had an issue with the New-AzureQuickVM cmdlet returning an error regarding the CurrentStorageAccountName not being found.  A quick Googling took me to Stephen Owen’s blog on how to resolve this error.  You’ll want to read up on this post and update your Azure subscription info if necessary.  You’ll likely have to.

The ‘One-Liner’

Building a one-line command is pretty easy, provided that you have some necessary things configured before deploying.  For my purposes, I’ll be using the New-AzureQuickVM cmdlet.  At a bare minimum for a Windows deployment, you’ll need the following bits of information:

  • You need to specify that you want to deploy a Windows server. (-windows)
  • The location of your preferred Azure datacenter (-location)
  • The image name you wish to deploy. (-imagename)
  • The name of the server you wish to deploy.(-name)
  • The Azure Cloud Services name to deploy the server into. (-servicename)
  • The user name of the Administrator account. (-adminusername)
  • The password of the Administrator account. (-password)

But before we can do the assemblage, we need to gather some information first; such as the information for location and imagename.  Getting the location is fairly straightforward.  Using the Get-AzureLocation cmdlet, you can get a listing of the datacenters that are available globally.



For our purposes, we’ll use the West US datacenter location.  Now to look up the image name, we’ll use the Get-AzureVMImage since we’re not using any custom images.


Now you’ll find that when you run this, it’s going to pull all of the images available through Azure; 470 at the time of this writing to be exact!  So we’re going to try to pare this down a bit.


(Get-AzureVMImage).where({$PSItem.Label -like "*Windows Server 2012 R2*"}) | Measure-Object


Well, almost.  But if we whittle it down a bit further…


Ah!  Better.  Now that we’ve gotten down to the base server load, we can take a look and we’ll find that, like the images available in the image gallery in the New Virtual Machine wizard in Azure, you have three different dated versions available to choose from.  For the purposes of our implementation, we’ll just grab the latest image.


What we’ll be looking to grab from here is the long string of characters that is the image name to fulfill the image requirement for our command.  So let’s go ahead and snag this bit for our BaseImage variable and add our $Location variable as well.

$Location = 'West US'
$BaseImage = (Get-AzureVMImage).where({$PSItem.Label -like "*Windows Server 2012 R2 Datacenter*" -and $PSItem.PublishedDate -eq "2/11/2015 8:00:00 AM" })

So now we can build our command.  But I’d like to not have my commands run off the screen, so let’s do some splatting!

$Location = 'West US'
$BaseImage = (Get-AzureVMImage).where({$PSItem.Label -like "*Windows Server 2012 R2 Datacenter*" -and $PSItem.PublishedDate -eq "2/11/2015 8:00:00 AM" })
$AzureArgs = @{
 Windows = $True
 ServiceName = 'LWINerd'
 Name = 'TestSrv'
 ImageName = $BaseImage.ImageName
 Location = $Location
 AdminUserName = 'LWINAdmin'
 Password = 'b0b$y3rUncle'
New-AzureQuickVM @AzureArgs

And now we see that we have a new service in Azure…


And a new VM is spinning up!


And now we have our base script for building VMs in Azure.  Next post, we’ll be looking at creating availability sets through PowerShell, as well as assigning our VMs to specific virtual network address spaces, bringing in some parameterization and more!

***EDIT*** – For some reason I was previously under the impression that you have to create an availability set if you wanted to have multiple machines co-existing in the same cloud service.  This is not the case, but I’ll be exploring the creation of availability sets in my code next week nonetheless.