VM builds are probably the boring tasks that are repeatedly done by any vSphere Admins be it in Lab or Production, so it’s a good idea to automate them and spend time on better things. In this post i will be showing the script that i have been using since many years when i come across those VM builds and it only takes less than 5 min to create a VM – love automation!
In order to use the script, we need to actually create a OS customization first and this is a one time task and also we need to have a Windows VM Template created. Once you have it just bring up the PowerShell console and use the below script, the script prompts for VM name, Reserved IP, Windows Version and VM port group information and once you enter them and that’s it.
<# .SYNOPSIS This script deploys a VM from template, joins the Domain;Uses VMware built-in OS Customization. Tested for Windows Server 2008 R2 and 2012 R2. .DESCRIPTION Script prompts for name of the VM you want to deploy, IP, VLAN and Windows Version .NOTES Tested on PowerCLI v6 #> Param( [string]$VMName = (Read-Host "Enter the Name of the VM "), [string]$VMIP = (Read-Host "Enter the IP reserved for the VM "), [string]$PortGroup = (Read-Host "Enter the VLAN for the VM, example 10 "), [string]$Winver = (Read-Host "Enter the Windows version, example 2012 ") ) #Import PowerCLI Module Import-Module VMware.PowerCLI # Connect to vCenter Connect-VIServer vcenter.vmmaster.local # Choose the right nicmapping for the vlan if ($PortGroup -eq 10) { $vmvlan = 10 $pgnicmapping = "vlan10" $vmGateway = "<IP Here>" } elseif ($PortGroup -eq 20) { $vmvlan = 20 $pgnicmapping = "vlan20" $vmGateway = "<IP Here>" } # Choose the right template if ($Winver -eq 2008) { $vmTemplate =Get-Template -Name Template_Win_2008R2 } else { $vmTemplate = Get-Template -Name Template_Win_2012R2 } #Select Prod Cluster $vmCluster = Get-Cluster -Name <Cluster Name> #Select a Random Datastore connected to Prod Cluster $vmDatastore = $vmCluster | Get-Datastore | Where {($_.ExtensionData.Summary.MultipleHostAccess -eq "True") -and ($_.FreeSpaceMB -gt "102400") -and ($_.State -ne "Maintenance")} | Get-Random #Clone the Customization Spec $vmSpecification = Get-OSCustomizationSpec -Name Windows_Builds | New-OSCustomizationSpec -Name WindowsTemp -Type NonPersistent #Update the portgroup and gateway based on the VLAN entered $tempnicmapping = Get-OSCustomizationSpec $vmSpecification | Get-OSCustomizationNicMapping | Set-OSCustomizationNicMapping -ipmode UseStaticIP -IpAddress $VMIP -SubnetMask 255.255.255.0 -DefaultGateway $vmGateway -Dns <DNS IPs here> #Build the VM New-VM -Name $VMName -Template $vmTemplate -OSCustomizationSpec $vmSpecification -ResourcePool $vmCluster -Datastore $vmDatastore -DiskStorageFormat Thin Write-Host " New VM Details `n Name:`t $VMName `n OS:`t Windows Server $Winver R2 `n IPAddress:`t $VMIP `n Datastore:`t $vmDatastore" -ForegroundColor Gray Start-Sleep -Seconds 30 #Set the right portgroup for the VM Get-VM $VMName | Get-NetworkAdapter -Name "Network adapter 1" | Set-NetworkAdapter -NetworkName $pgnicmapping -Confirm:$false -StartConnected:$True #Power On the VM for the customization to start Write-Host " Powering on the VM $VMName" -ForegroundColor Green $vm = Start-VM $VMName -Confirm:$false Write-Host "`n Waiting for the customization to complete! Monitor the console to see the progress.......... `n" -ForegroundColor Green while (Get-VM $VMName | where {$_.PowerState -eq "PoweredOn"}) { $vmEvents = Get-VIEvent -Entity $VMName $succeeded = $vmEvents | Where { $_.GetType().Name -eq "CustomizationSucceeded" } $failed = $vmEvents | Where { $_.GetType().Name -eq "CustomizationFailed" } if ($failed) { Write-Host " Customization failed!" -ForegroundColor Red return $False } if($succeeded) { Write-Host " Customization Complete!" -ForegroundColor Green return $True } Start-Sleep -Seconds 10 }
If you are interested in procedure for creating Customization Specification, here it is. Adding batch files that can install and configure config management tools like Puppet, Chef in the Run Once section will actually ensure all the needed configurations are present for the application.
Hope this was informative. Thanks!