Chocolatey, Remote PowerShell and Azure IAAS – automating dev box creation

Hi All,

Recently I’ve needed a throw away environment and so turned to Azure IAAS to get a nice VM up and running quickly. To do this I’ve turned to Chocolatey, its a great utility for installing application and I’d been using it to install simple bits and bobs on my local machine. I fell in love, there are some caveats to be aware of but in short its awesome.

So I started playing, the aim – Automate the create and installation of an Azure VM with all the dev tools I needed with no user interaction.

  1. I came across a great post by Michael Washam which details how to boot a Azure VM then initiate remote powershell onto the box. This is awesome, it let me spin up a box and set it off installing the windows features.
  2. I tweaked this script a bit to remove the need for the credentials prompt and added a quick check to ensure I had the right privileges on the box for it to run correctly.
  3. Once the Windows Features are finished I install Chocolatey and add in all the nice programs that you’d like on your dev box. Vs2012, Linqpad, notepad++ etc
  4. Chocolatey also lets you install from the webplatform installer so I then set about installing all the stuff I need from webpi. AzurePowershell, SQLExpressTools et
  5. Wait for the script to complete and all being well you’ve got a nice devbox ready to go!
  6. For good measure the script kicks off a RDP session to the box and interactive remote powershell to finish.

If (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(`
 [Security.Principal.WindowsBuiltInRole] "Administrator"))
{
 Write-Warning "You do not have Administrator rights to run this script!`nPlease re-run this script as an Administrator as it will need to install the remote certificate."
 Break
}

$ErrorActionPreference = "Stop"
$user = "usernamegoeshere"
$pwd = "passwordgoeshere"
$SecurePassword = $pwd | ConvertTo-SecureString -AsPlainText -Force
$svcName = "servicenamegoeshere"
$VMName = "vmnamegoeshere"
$location = "North Europe" #change as needed
$imageName = "a699494373c04fc0bc8f2bb1389d6106__Windows-Server-2012-R2-Preview-201306.01-en.us-127GB.vhd" #or whichever azure image you'd like as the base.
$credential = new-object -typename System.Management.Automation.PSCredential -argumentlist $user,$SecurePassword

New-AzureVMConfig -Name $VMName -InstanceSize "ExtraSmall" -ImageName $imageName |
 Add-AzureProvisioningConfig -Windows -AdminUsername $user -Password $pwd |
 Add-AzureEndpoint -Name "http" -Protocol tcp -LocalPort 80 -PublicPort 80 |
 New-AzureVM -ServiceName $svcName -Location $location -WaitForBoot
function InstallWinRMCert($serviceName, $vmname)
{
 $winRMCert = (Get-AzureVM -ServiceName $serviceName -Name $vmname | select -ExpandProperty vm).DefaultWinRMCertificateThumbprint

 $AzureX509cert = Get-AzureCertificate -ServiceName $serviceName -Thumbprint $winRMCert -ThumbprintAlgorithm sha1

 $certTempFile = [IO.Path]::GetTempFileName()
 $AzureX509cert.Data | Out-File $certTempFile

 # Target The Cert That Needs To Be Imported
 $CertToImport = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2 $certTempFile

 $store = New-Object System.Security.Cryptography.X509Certificates.X509Store "Root", "LocalMachine"
 $store.Certificates.Count
 $store.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadWrite)
 $store.Add($CertToImport)
 $store.Close()

 Remove-Item $certTempFile
}

# Get the RemotePS/WinRM Uri to connect to
$uri = Get-AzureWinRMUri -ServiceName $svcName -Name $VMName

# Using generated certs – use helper function to download and install generated cert.
InstallWinRMCert $svcName $VMName

# Use native PowerShell Cmdlet to execute a script block on the remote virtual machine
Invoke-Command -ConnectionUri $uri.ToString() -Credential $credential -ScriptBlock {
 write-host "Installing windows features"
 $logLabel = $((get-date).ToString("yyyyMMddHHmmss"))
 $logPath = "$env:TEMPinit-webservervm_webserver_install_log_$logLabel.txt"
 Import-Module -Name ServerManager

 #example features
 Install-WindowsFeature -Name Web-Server -IncludeManagementTools -LogPath $logPath

 #nb This feature is required for webpi installer to function correctly
 install-windowsfeature -name NET-Framework-Features -LogPath $logPath

write-host "Installling Choc"

iex ((new-object net.webclient).DownloadString("http://chocolatey.org/install.ps1"))

write-host "installing dev tooling"
 #example packages
 cinst VisualStudio2012Ultimate
 cinst MsSqlServer2012Express
 cinst linqpad4
 cinst notepad++
 cinst SQLManagementStudio -source webpi
 cinst SQLExpressTools -source webpi
 cinst VWDOrVs11AzurePack -source webpi
 cinst WindowsAzurePowershell -source webpi
}
Write-host "Install command finished - Launching remote desktop and interactive remote powershell session to devbox"
Get-AzureRemoteDesktopFile -ServiceName $svcName -Name $VMName –Launch
Enter-PSSession -ConnectionUri $uri.ToString() -Credential $credential

By:

Posted in:


4 responses to “Chocolatey, Remote PowerShell and Azure IAAS – automating dev box creation”

  1. Wow, if this works, my life got 100% easier. Trying this after seeing chocolatey SoCal Code Camp today. I am creating dev/test SharePoint developer vms in the cloud and do not like relying on sysprepped VMs, and want to leverage the Azure OOTB images that are regularly updated. Thank you! I will check back soon with the progress!

Leave a comment

Blog at WordPress.com.