Sunday, December 2, 2012

PowerCLI - Deploying VM from template with customization spec

Reproducing an issue recently required me to deploy 20 VM's across 4 hosts that each had 5 datastores (4 VM's on each datastore, one from each host). The datastores were named nfs-[1-5]. Once I had the template VM created with the tools I needed and the customization spec, I was able to deploy the VM's across the hosts/datastores with the following PowerCLI code:
1..5 | Foreach { New-VM -vmhost 192.168.10.244 -Name Win2k8-1-$_ -Template Win2k8Template -Datastore nfs-$_ -OSCustomizationSpec TM-WIN2k8 }
1..5 | Foreach { New-VM -vmhost 192.168.10.245 -Name Win2k8-2-$_ -Template Win2k8Template -Datastore nfs-$_ -OSCustomizationSpec TM-WIN2k8 }
1..5 | Foreach { New-VM -vmhost 192.168.10.246 -Name Win2k8-3-$_ -Template Win2k8Template -Datastore nfs-$_ -OSCustomizationSpec TM-WIN2k8 }
1..5 | Foreach { New-VM -vmhost 192.168.10.247 -Name Win2k8-4-$_ -Template Win2k8Template -Datastore nfs-$_ -OSCustomizationSpec TM-WIN2k8 }
Each VM was using ~20GB, and the whole deployment took approximately an hour. I found a variation of the above on another blog (http://virtuallymikebrown.com/2012/02/17/deploy-a-vm-from-template-with-powercli/) where he was able to pipe the New-VM command to Start-VM but for whatever reason this didn't work for me, I was getting the error: "New-VM : 12/2/2012 5:06:34 PM New-VM Operation is not valid due to the current state of the object." I didn't look into this too much and instead just ran the following loop after the above was done:
$VMs = Get-VM -Name "Win2k8-*"
foreach ($vm in $VMs)  {
  Write-Host "Starting " -NoNewLine
  Write-Host $vm.Name 
  Start-VM $vm.Name
}
The final outcome in vCenter looked like: