OSCustomization for VM builds using PowerCLI

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.

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.
Script prompts for name of the VM you want to deploy, IP, VLAN and Windows Version
Use PowerCLI v6 and above preferably one pulled from PSGallery, PowerShell v4 and above

[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 vSphere02-SC9.virginam.com
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
$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 -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

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.

This slideshow requires JavaScript.

Hope this was informative. Thanks!


Login to vCenter via PowerCLI without entering Credentials

Bored of entering your credentials every time you login to your infrastructure via PowerCLI? Ideally, if you are managing the virtual infrastructure of the same domain as the one you logged in, you should be already able to connect to vCenter and PowerCLI using your logged in credentials. Most of the times this is not the case in multi client support environment. Continue reading

Get Snapshots older than X Days – PowerCLI

Finding the virtual machines running on snapshots is a very common task and in this post i am going to show you a one liner that can pull snapshots older than X days. Here we go!

This is very critical because of the bad effects snaoshots can have on the virtual machines. VM’s running on snapshots for more than 72hrs are not supported by VMware. Continue reading

Rescan HBA on all hosts in a Cluster – PowerCLI

When a new storage has been presented to all the hosts in a cluster, sometimes we may need to scan the HBA’s for the ESXi to see the storage. Most of the times when you rescan HBA on one ESXi, the others also see the storage but sometimes we may have to rescan HBA on all the hosts. Continue reading

Snapshot List of VM’s from csv – PowerCLI

Many may have come across a situation where you need to take snapshot on a set a VMs for maintenance activities. In an environment having 1500+ machines, this can be tedious.The below command conmes in handy for such tasks. Continue reading

Enable SSH on ESXi host – PowerCLI

To enable SSH on one host, use the below command from PowerCLI.

Get-VMHost esxi-1.vmmaster.local | Get-VMHostService | Where { $_.Key -eq "TSM-SSH" } | Start-VMHostService Continue reading 

Enable/Disable SSH on all ESXi hosts

Sometime you may see a need to enable or disable SSH on all hosts in a cluster. This post will help you achieve that quickly using the PowerCLI.

Connect to vCenter Server using PowerCLI and use the below command to check the status of the SSH and ESXi Shell on hosts. Continue reading