2016-06-30

PowerShell function to create Azure ARM VM with Public IP

This function is intended to reside within the logic of a larger script for deploying an entire resource group. The function should ideally be fed from a JSON or XML configuration file.
It takes a whole bunch of inputs relating to Azure VMs and provisions a VM within a resource group and VNet with a public IP. The Network Security Group settings need to be amended as required.
I've extracted some of the required variables, but these could also be passed as parameters.

[string]$resGroup = "IIOS" [string]$location = "australiaeast" [int]$script:ipStart = 4 [string]$saName = $($saName -creplace '[^a-zA-Z0-9]','').ToLower() [string]$vnName = $($resGroup +"-vNet1") function Create_VMRole([string]$vmName, [string]$vmSize, [string]$vmDesc, [int]$dataDiskSize, [string]$PublisherName, [string]$Offer, [string]$Skus) { while(($vmName.length -gt 15) -or !$vmName){ Write-Host "Virtual Machine Name '$vmName' is too long or empty" "Yellow" [string]$vmName = read-host "Please enter a valid Virtual Machine Name..." Write-Host "`nYou entered '$vmName'`n" "Yellow" } Write-Host "[CREATING] $vmDesc Virtual Machine '$vmName'" $vmAvailabilitySet = $($vmName +"AvailabilitySet") if(!($vmSet = Get-AzureRMAvailabilitySet -Name $vmAvailabilitySet -ResourceGroupName $resGroup)) { Write-Host "[CREATING] AvailabilitySet '$vmAvailabilitySet' for $vmDesc Virtual Machine '$vmName'" $vmSet = New-AzureRMAvailabilitySet -Name $vmAvailabilitySet -ResourceGroupName $resGroup -Location $location } $vnet = Get-AzureRMVirtualNetwork -Name $vnName -ResourceGroupName $resGroup Write-Host "[CREATING] PublicIpAddress for '$vmName'" $pip = New-AzureRMPublicIpAddress -Name $($vmName +"-PublicIP1") -ResourceGroupName $resGroup -Location $location -AllocationMethod Dynamic $nicIP = $("10.0.0." + $script:ipStart++) Write-Host "[CREATING] NetworkInterface with PrivateIP '$nicIP' for '$vmName'" $nic = New-AzureRMNetworkInterface -Name $($vmName +"-NIC1") -ResourceGroupName $resGroup -Location $location -SubnetId $vnet.Subnets[0].Id -PublicIpAddressId $pip.Id -PrivateIpAddress $nicIP $vm = New-AzureRMVMConfig -VMName $vmName -VMSize $vmSize -AvailabilitySetId $vmSet.Id $storageAcc = Get-AzureRMStorageAccount -ResourceGroupName $resGroup -Name $saName if($dataDiskSize -gt 0) { $vhdURI = $($storageAcc.PrimaryEndpoints.Blob.ToString() + "vhds/" + $vnName +"-"+ $vmName +"-Data1.vhd") Add-AzureRMVMDataDisk -VM $vm -Name "Data1" -DiskSizeInGB $dataDiskSize -VhdUri $vhdURI -CreateOption empty } $vm = Set-AzureRMVMOperatingSystem -VM $vm -Windows -ComputerName $vmName -Credential $vmCred -ProvisionVMAgent -EnableAutoUpdate #-TimeZone $TimeZone $vm = Set-AzureRMVMSourceImage -VM $vm -PublisherName $PublisherName -Offer $Offer -Skus $Skus -Version "latest" $vm = Add-AzureRMVMNetworkInterface -VM $vm -Id $nic.Id $osDiskUri = $($storageAcc.PrimaryEndpoints.Blob.ToString() + "vhds/" + $vnName +"-"+ $vmName +"-System.vhd") $vm = Set-AzureRMVMOSDisk -VM $vm -Name "System" -VhdUri $osDiskUri -CreateOption fromImage $newVM = New-AzureRMVM -ResourceGroupName $resGroup -Location $location -VM $vm return $newVM } Example usage: Create_VMRole "dbVM1" "Standard_D3_V2" "SQL Server Primary" 300 "MicrosoftSQLServer" "SQL2014SP1-WS2012R2" "Standard"