Skip to content

Instantly share code, notes, and snippets.

@mmckechney
Last active October 12, 2017 16:06
Show Gist options
  • Save mmckechney/78153c3a95cec9fa34c8d96e81d20355 to your computer and use it in GitHub Desktop.
Save mmckechney/78153c3a95cec9fa34c8d96e81d20355 to your computer and use it in GitHub Desktop.
Automates the steps to go from a VHD file in Azure storage to create a VM in Azure DevTest Labs
param
(
[Parameter(Mandatory = $true)]
[string] $subscriptionId = $(Read-Host -prompt "Specify the subscription Id"),
[Parameter(Mandatory = $true)]
[string] $labResourceGroup = $(Read-Host -prompt "Specify the resource group for the DevTest Lab"),
[Parameter(Mandatory = $true)]
[string] $labName = $(Read-Host -prompt "Specify the name of the DevTest Lab"),
[Parameter(Mandatory = $true)]
[string] $labVirtualNetworkName = $(Read-Host -prompt "Specify the name of the DevTest Lab virtual network"),
[Parameter(Mandatory = $true)]
[string] $labSubNetName= $(Read-Host -prompt "Specify the name of the DevTest Lab subnet "),
[Parameter(Mandatory = $true)]
[string] $sourceStorageResourceGroup = $(Read-Host -prompt "Specify the resource group for the storage account where the source VHD resides"),
[Parameter(Mandatory = $true)]
[string] $vhdUri = $(Read-Host -prompt "Specify the VHD URI"),
[Parameter(Mandatory = $true)]
[string] $customImageName = $(Read-Host -prompt "Specify the name of the custom image to create"),
[Parameter(Mandatory = $false)]
[string] $customImageDescription = $(Read-Host -prompt "Specify a description for the customer image"),
[Parameter(Mandatory = $true)]
[string] $newVMName = $(Read-Host -prompt "Specify a name for the new VM"),
[Parameter(Mandatory = $true)]
[string] $newVMSize = $(Read-Host -prompt "Specify a size for the new VM"),
[Parameter(Mandatory = $true)]
[string] $userName = $(Read-Host -prompt "Specify a default user name for the VM"),
[Parameter(Mandatory = $true)]
[string] $pw = $(Read-Host -prompt "Specify a default password for the VM")
)
$securePassword = ConvertTo-SecureString $pw -AsPlainText -Force
# Select the desired Azure subscription.
Select-AzureRmSubscription -SubscriptionId $subscriptionId
# Get the lab object.
$lab = Get-AzureRmResource -ResourceId ('/subscriptions/' + $subscriptionId + '/resourceGroups/' + $labResourceGroup + '/providers/Microsoft.DevTestLab/labs/' + $labName)
# Get the lab storage account and lab storage account key values.
$labStorageAccount = Get-AzureRmResource -ResourceId $lab.Properties.defaultStorageAccount
$labStorageAccountKey = (Get-AzureRmStorageAccountKey -ResourceGroupName $labStorageAccount.ResourceGroupName -Name $labStorageAccount.ResourceName)[0].Value
$labStorageContext = New-AzureStorageContext -StorageAccountName $labStorageAccount.ResourceName -StorageAccountKey $labStorageAccountKey
#Get source storage info from URI
$splitOptions = [System.StringSplitOptions]::RemoveEmptyEntries
$urlArray = $vhdUri.Split('/',$splitOptions)
$sourceStorageAccountName = $urlArray[1].Split('.')[0]
$sourceStorageAccountKey = (Get-AzureRmStorageAccountKey -ResourceGroupName $sourceStorageResourceGroup -Name $sourceStorageAccountName)[0].Value
$sourceContext = New-AzureStorageContext -StorageAccountName $sourceStorageAccountName -StorageAccountKey $sourceStorageAccountKey
$destinationVhdName = "$($customImageName.ToLower()).vhd"
$destinationContainerName = "generatedvhds"
#check to see if the container exists
$containerExists = Get-AzureStorageContainer -Name $destinationContainerName -Context $labStorageContext
if($containerExists -eq $null)
{
New-AzureStorageContainer -Name $destinationContainerName -Context $labStorageContext
}
#check to see if the destination file already exists
$exists = Get-AzureStorageBlob -Context $labStorageContext -Container $destinationContainerName -Blob $destinationVhdName -ErrorAction SilentlyContinue
if($exists -eq $null)
{
#copy the VHD into the DevTest Lab storage account
$copyResult = Start-AzureStorageBlobCopy -SourceUri $vhdUri -Context $sourceContext -DestContext $labStorageContext -DestContainer $destinationContainerName -DestBlob $destinationVhdName
Do
{
$status = $copyResult | Get-AzureStorageBlobCopyState
Write-Output "VHD Copy status: $($status.Status)"
if($status.Status -eq "Pending")
{
Start-Sleep 20
}
} While ($status.Status -eq "Pending")
}
else
{
Write-Output "VHD of name '$destinationVhdName' already exists in storage account: '$labSubNetName', container '$destinationContainerName'"
}
$newBlob = Get-AzureStorageBlob -Blob $destinationVhdName -Container $destinationContainerName -Context $labStorageContext
#Check to see if the custom image already exists
$imageExists = Get-AzureRmResource -ResourceGroupName $labResourceGroup -ResourceType "Microsoft.DevTestLab/labs/customimages" -ResourceName "$labName/$customImageName" -ApiVersion 2016-05-15 -ErrorAction SilentlyContinue
if($imageExists -eq $null)
{
# Set up the parameters object for the custom image.
$imageParameters = @{existingLabName="$($lab.Name)"; existingVhdUri= "$($newBlob.ICloudBlob.StorageUri.PrimaryUri.AbsoluteUri)"; imageOsType='windows'; isVhdSysPrepped=$false; imageName=$customImageName; imageDescription=$customImageDescription}
# Create the custom image.
Write-Output "Creating Custom Image: $customImageName"
New-AzureRmResourceGroupDeployment -ResourceGroupName $lab.ResourceGroupName -Name CreateCustomImage_$customImageName -TemplateUri 'https://raw.githubusercontent.com/Azure/azure-devtestlab/master/Samples/201-dtl-create-customimage-from-vhd/azuredeploy.json' -TemplateParameterObject $imageParameters
Do
{
$state = (Get-AzureRmResourceGroupDeployment -ResourceGroupName $labResourceGroup -Name CreateCustomImage_$customImageName).ProvisioningState
Write-Output "Custom Image provisioning: $state"
if($state -eq "Running")
{
Start-Sleep -s 10
}
}While( $state -eq "Running")
}
else
{
Write-Output "Custom image with name '$customImageName' already exists"
}
#check to see if the VM already exists
$vmExists = Get-AzureRmResource -ResourceGroupName $labResourceGroup -ResourceType Microsoft.DevTestLab/labs/virtualmachines -ResourceName "$labName/$newVMName" -ApiVersion 2016-05-15 -ErrorAction SilentlyContinue
if($vmExists -eq $null)
{
# Set up the parameters object for the new VM.
$vmParameters = @{newVMName="$newVMName"; labName="$labName"; size="$newVMSize"; customImageName="$customImageName"; virtualNetworkName="$labVirtualNetworkName"; subNetName="$labSubNetName"; userName="$userName"; password="$securePassword"}
# Create the VM from the custom Image.
Write-Output "Creating New VM: $newVMName"
New-AzureRmResourceGroupDeployment -ResourceGroupName $lab.ResourceGroupName -Name CreateNewVM_$newVMName -TemplateUri 'https://gist.githubusercontent.com/mmckechney/9bb5c26dc20736d8b94a74927f1b53cf/raw/4316fd2fec2c2f5fba4f1e4352ec33c2782558a7/dtl-create-vm-from-customimage.json' -TemplateParameterObject $vmParameters
Do
{
$state = (Get-AzureRmResourceGroupDeployment -ResourceGroupName $labResourceGroup -Name CreateNewVM_$newVMName).ProvisioningState
Write-Output "VM provisioning: $state"
if($state -eq "Running")
{
Start-Sleep -s 10
}
}While( $state -eq "Running")
}
else
{
Write-Output "VM with the name '$newVMName' already exists"
}
Write-Output "Finished"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment