In this article, I’m going to show you how you can build an entire Azure lab setup with a single line of PowerShell.
This lab environment will allow you to be 100% sure your students can follow along with your training material exactly.
I write a lot of how-to posts like this. I also author a lot of online training courses. This kind of training content always requires me to define a Prerequisites section. The Prerequisites section has to go into detail on what it takes to get the reader’s environment exactly like mine. I grew tired of that and decided to automate it.
When you build technical, how-to content like this, all trainers struggle with getting you (the learner) in sync with them (the trainers). We can provide scripts for you to run but they always fall short of getting everything.
I thought to myself, why can’t I simply tell students to run a one-line PowerShell command and have the entire lab environment built for them exactly how mine is? It turns out, it’s possible!
The only requirement is the student’s own Azure subscription.
Does this sound familiar when starting a new course?
So many trainers must run through an entire section to train you to build the demo environment just to get started! Now how about this? Regardless if you’re building a lab environment with a single machine or an entire datacenter, the process is the same.
“We will be working with a remote Windows Server and a Windows 10 workstation. When the environment is built, your username will be 'foo' and your password will be 'far.' The IP address to connect to is X.X.X.X.”
Notice that I provide a username, password and an IP address to RDP to, to get started. That’s it!
To provision the entire lab comes down to opening up a PowerShell console and running one line; the labsetup.ps1 script.
The lab environment automation project I’m about to share involves six rough steps.
My goal was to remove as many steps a student would have to go through to get a lab environment up and running.
There’s no secret sauce in this step. Create any old GitHub repo and call it anything you wish. I’ve called mine devops-from-the-ground-up-resources since the course I was build this for was called DevOps from the Ground Up.
This is not going to be an article on how to create Azure ARM templates. There are plenty of resources already out there to do that. If you’d like to see the one I’ve created for this project, check it out here.
The lab setup script is where the magic happens. This is the script the student downloads and executes automatically. If you’d like to download this script and see it in its entirety, feel free to do so here.
The lab setup script consists of a few different sections:
When the student downloads from my public GitHub repo and executes the lab setup script like below, the magic starts to happen:
iex ((New-Object System.Net.WebClient).DownloadString('https://raw.githubusercontent.com/adbertram/devops-from-the-ground-up-resources/master/labsetup.ps1'))
The script requires some PowerShell cmdlets to interact with Azure. The student will need the Azure PowerShell module. They will also need to be authenticated to their subscription.
## Download the Azure PowerShell module if the student doesn't have it
if (-not (Get-Module -Name Azure -ListAvailable -ErrorAction Ignore)) {
Install-Module -Name Azure -Force
}
## If the student isn't already authenticated to Azure, ask them to
if (-not (Get-AzContext)) {
Connect-AzAccount
}
Once the script itself is downloaded, it then go back out to GitHub and downloads the ARM template. Below, the script hides the annoying progress bar that Invoke-WebRequest brings up and saves the ARM template locally.
## Hide the prog bar generated by Invoke-WebRequest
$progPrefBefore = $ProgressPreference
$ProgressPreference = 'SilentlyContinue'
## Download the ARM template
$templatePath = "$env:TEMP\lab.json"
$url = 'https://raw.githubusercontent.com/adbertram/devops-from-the-ground-up-resources/master/lab.json'
Invoke-WebRequest -Uri $url -OutFile $templatePath
The script then create’s the course lab’s resource group if it doesn’t exist. This resource group is where all of the course resources will be created in.
## Azure resource group will be the course name
$rgName = "$($CourseName -replace ' ','-')"
## Create the lab's resource group
if (-not (Get-AzResourceGroup -Name $rgName -Location $AzureRegion -ErrorAction Ignore)) {
$null = New-AzResourceGroup -Name $rgName -Location $AzureRegion
}
The script then kicks off the Azure ARM deployment via the New-AzResourceGroupDeployment cmdlet.
## Deploy lab using the ARM template just downloaded
$deploymentName = "$rgName-Deployment"
$null = New-AzResourceGroupDeployment -Name $deploymentName -ResourceGroupName $rgName -TemplateFile $templatePath -Verbose
$deploymentResult = (Get-AzResourceGroupDeployment -ResourceGroupName $rgName -Name $deploymentName).Outputs
The student is then notified of the public IP addresses of the Azure virtual machines created for them.
Write-Host "Your lab VM IPs to RDP to are:"
$vmIps = @()
foreach ($val in $deploymentResult.Values.Value) {
$pubIp = Get-AzResource -ResourceId $val
$vmName = $pubIp.Id.split('/')[-1].Replace('-pubip', '')
$ip = (Get-AzPublicIpAddress -Name $pubip.Name).IpAddress
$vmIps += [pscustomobject]@{
Name = $vmName
IP = $ip
}
Write-Host "VM: $vmName IP: $ip"
}
The final step the script runs through is automatically connecting to the VM via mstsc.exe. This eliminates the need for the user to do anything at all to get started.
## If the student is on Windows, prompt and connect for them. Otherwise, tell them the IPs to connect to
if ($env:OS -eq 'Windows_NT') {
$rdpNow = Read-Host -Prompt "RDP to the required host ($RequiredRdpVM) now (Y,N)?"
if ($rdpNow -eq 'Y') {
$requiredVM = $vmIps.where({ $_.Name -eq $RequiredRdpVM })
$ip = $requiredVM.IP
mstsc /v:$ip
} else {
Write-Host "Please RDP to the VM [$($RequiredRdpVM) : $ip] now to begin course. The username and password are provided in the Lab Preparation section of the chapter."
}
} else {
Write-Host "Please RDP to the VM [$($RequiredRdpVM) : $ip] now to begin course. The username and password are provided in the Lab Preparation section of the chapter."
}
You have seen that you can completely automate a lab environment for any purposes (not just for training) by running a single PowerShell script!
I hope this project of mine gives you a foundation to create a more robust tool! If you do improve upon it, let me know. I’d be glad to update this post and the GitHub repo.
Adam Bertram is a 25+ year IT veteran and an experienced online business professional. He’s a successful blogger, consultant, 6x Microsoft MVP, trainer, published author and freelance writer for dozens of publications. For how-to tech tutorials, catch up with Adam at adamtheautomator.com, connect on LinkedIn or follow him on X at @adbertram.
Let our experts teach you how to use Sitefinity's best-in-class features to deliver compelling digital experiences.
Learn MoreSubscribe to get all the news, info and tutorials you need to build better business apps and sites