Create an SP2013 VM on Azure using PowerShell

A few weeks ago Windows Azure IaaS features have reached GA. Since then I'm continuously replacing my OnPremise SharePoint development machines by new Azure VMs. In order to save money I’m going to remove the virtual machines as soon as I don’t need them. Automating the process of creation and deletion is essential for me, because I don’t want to spend a few minutes each day in PowerShell to just get my machine up and running.

For my production environment I’ve of course created a VHD by my own, but for this post I’ll fall back to the SharePoint 2013 Trial Image created by Microsoft and available in the Windows Azure Virtual Machine Gallery.

Install Windows Azure PowerShell cmdlets

Before you can use the script on your machine you’ve to install Windows Azure PowerShell cmdlets.

Ensure ExecutionPolicy and Admin Privileges

You should start the PowerShell as an Administrator and you should execute the following command in order to be able to execute my script Set-ExecutionPolicy RemoteSigned

While playing around with Windows Azure PowerShell cmdlets I’ve seen many articles describing how to set the AzureSubscription by using these damn PublishingSettings files. Each time I’ve tried to use them I ran into the following issues (perhaps can someone provide any solution? Then leave a comment)

  1. When I execute Get-AzurePublishingSettingsFile or click the ‘Download Publishing Settings File’ button in VS my browser fires up and tries to download the file. This download ONLY works in IE.
  2. Each time I try to download a PublishingSettingsFile new dev certs were added to my Azure Portal
  3. I’ve multiple Azure Subscriptions and each time I download or import a PublishingSettingsFile I’ve to define the default subscription… why can’t I define it once in the portal??

Because of these issues I decided to authenticate using a valid X509 Certificate created by my own in opposite of the PublishingSettingsFile. But for now back to my script.

My PowerShell Script offers the following features

  • Configuring Azure Subscription using X509 Cert
  • Selecting or Creating an Azure Affinity Group
  • Selecting or Creating an Azure Storage Account
  • Select the SharePoint 2013 Trial Image from the Windows Azure Image Gallery
  • Create a new Azure VM within the given Affinity Group
  • Storing the Azure VM Configuration locally
  • Storing the Azure RDP Connection locally

For the last two points I recommend you to use SkyDrive. By using SkyDrive I’ve these important files on all my devices.

The Script

#I use this script to easily create a new Azure VM based on a Gallery template 
# author: Thorsten Hans <[email protected]> 
Clear-Host Write-Host '# # # Windows Azure VM Automation Script # # #' -ForegroundColor Green  
Write-Host "Version:`t0.1" -ForegroundColor Green  
Write-Host "Author:`t`tThorsten Hans <[email protected]>" -ForegroundColor Green  
Write-Host "Blog:`t`t" -ForegroundColor Green 

# Load Windows Azure PowerShell cmdlets 
if(@(Get-Module | Where-Object { $_.Name -eq 'Azure'}).Count -eq 0){  
  Import-Module 'C:Program Files (x86)Microsoft SDKsWindows AzurePowerShellAzureAzure.psd1' 

## Some functions to reduce code duplication.. DRY 
## Yes I'm a dev... IT Pros don't care about code duplication 
Function EI-Create-AzureAffinityGroup{  
  param($name, $location) 

  Write-Host 'Creating Affinity Group' -ForegroundColor Green 
  New-AzureAffinityGroup -Name $name -Location $location 
  Write-Host ("Affinity Group '{0}' has been created" -f $name) 

  return Get-AzureAffinityGroup -Name $name 

Function EI-Create-StorageAccount {  
  param($name, $affinityGroup) 

  Write-Host 'Creating Storage Account' -ForegroundColor Green 
  New-AzureStorageAccount -StorageAccountName $name -Label $name -Description $name -AffinityGroup $affinityGroup.Name 
  Write-Host ("Storate Account '{0}' has been created" -f $name) 

  return Get-AzureStorageAccount -StorageAccountName $name 

# Grab contextual information, if you don't have some of these information, leave it blank 

$storageName = Read-Host -Prompt 'Storage Name' 
$affinityName = Read-Host -Prompt 'Affinity Group Name' 

# Try to load the Subscription, if not found, configure subscription by using X.509 Cert 

$subscription = Get-AzureSubscription -Current -ErrorAction SilentlyContinue -ErrorVariable SubscriptionNotConfigured 

if($SubscriptionNotConfigured -ne $null){  
  $certThumbprint = Read-Host -Prompt "X.509 Thumbprint" 
  $subscriptionId = Read-Host -Prompt "Subscription ID " 
  $subscriptionName = Read-Host -Prompt "Subscription Name" 
  $cert = Get-Item Cert:CurrentUserMy$certThumbprint 

  Set-AzureSubscription -SubscriptionName $subscriptionName -SubscriptionId $subscriptionId -Certificate $cert   
  $subscription = Get-AzureSubscription -Current 

# Check Affinity Group Name provided by user 

  $affinityName = Read-Host -Prompt 'Provide a name for the new Affinity Group' 
  # Try to load affinity group 
  $affinityGroup = Get-AzureAffinityGroup -Name $affinityName -ErrorAction SilentlyContinue -ErrorVariable AffinityGroupNotFound 

  Write-Host 'Affinity Group not found... Creating new one...' -ForegroundColor Yellow 
  $location = Read-Host -Prompt 'Provide a location for the new Affinity Group' 
  $affinityGroup = EI-Create-AzureAffinityGroup $affinityName $location 

# Check Storage Account 

  $storageName = Read-Host -Prompt 'Provide a name for the new Storage Account' 
  # Try to load storage account 
  $storageAccount = Get-AzureStorageAccount -StorageAccountName $storageName -ErrorAction SilentlyContinue -ErrorVariable StorageNotFound 

  Write-Host 'Storage Account not found... Creating new one...' -ForegroundColor Yellow 
  $storageAccount = EI-Create-StorageAccount $storageName $affinityGroup 

#Associate Storage Account with current Subscription 

Set-AzureSubscription -SubscriptionName  
$subscription.SubscriptionName -CurrentStorageAccount $storageName 

#Load SharePoint 2013 Trial Image from Azure Gallery 
Write-Host 'Loading SharePoint Image from Azure Gallery...' -ForegroundColor Green  
$SharePointImages = Get-AzureVMImage | Where-Object { $_.PublisherName -eq 'Microsoft SharePoint Group'} 

#Creating Azure VM from Template Write-Host 'Creating Windows Azure Virtual Machine' -ForegroundColor Green $vxName = Read-Host -Prompt 'Enter virtual machine name' 
$adminUserName = Read-Host -Prompt 'Enter Admin UserName' 
$password = Read-Host -Prompt 'Enter Password' -AsSecureString 
New-AzureQuickVM -Windows -ServiceName $vxName -Name $vxName -ImageName $SharePointImages[0].ImageName -AffinityGroup $affinityGroup.Name -InstanceSize ExtraLarge -AdminUsername $adminUserName -Password $password 

# I'm using SkyDrive to keep track of all my RDP Connections and Azure VM Configurations... 

Write-Host 'Exporting AzureVM Config and RDP Connection File' -ForegroundColor Green 

$azureVMConfigPath = ("C:UsersthSkyDriveAzureVMs{0}.xml" -f $vxName) $azureRDPPath = ("C:\\Users\\th\\SkyDrive\\RDPs\\{0}.RDP" -f $vxName) 
Export-AzureVM -ServiceName $vxName -Name $vxName -Path $azureVMConfigPath Get-AzureRemoteDesktopFile -ServiceName $vxName -Name $vxName -LocalPath $azureRDPPath 

Write-Host 'Azure VM has been created successfully'  

The PowerShell Script is also located on my github account at

Did you like that solution? Leave a comment!


comments powered by Disqus