VM MASS DEPLOYMENT with Powershell – Hyper-V

As you already know powershell is really useful in several scenarios where you need to automate task operations in windows world. I personally use “Powershell for Hyper-V” often (http://pshyperv.codeplex.com) especially in mass deployment scenarios where I need to deploy hundreds of virtual machines.

In this blog post I will use the powershell commandlet “NEW-VM” which I had used to create a loop within a script.

The goal here is to deploy, 384 VMs in a automated way :-)

Therefore I had created an MASTER-VM, which I had installed with all the required application (AV, Apps, Updates.…), tools and finally sysprepped the VM. The exactly command to generalize the VM –> SYSPREP /OOBE /GENERALIZE /SHUTDOWN  .

required preparations:

1. Download and Install Powershell Library from codeplex –> http://pshyperv.codeplex.com
2. Customize General Parameters in Script like
    - Number of required VMs (a.e. start at 1 and run 384 loops = 384 Vms)
    - Prefix name for your VMs (a.e. W2K8R2-T)
    - customize vRAM and vCPU settings
    - change destination drive where VMs should be created ("V:\"+$vmname)
    - copy your MASTER-VM (sysprepped) and amend location where MASTER-VHD can be found a.e. V:\Master\MASTER_R2.vhd
    - amend disk drive at "ADD-VMDISK" operation a.e. Add-VMDisk $vmname 0 0 ("V:\"+$vmname+"\"+$vmname+".vhd")Here we go with our powershell script:

Import-Module hyperv
# Here we import the hyper-v specific hyper-v module which must be downloaded and installed 1st

For ($Counter=1; $Counter -le 384; $Counter++) {
# most important section within this script. Here we define our loop and also how much VMs we want to create here. In my case the loop will start at 1 and run 384 times

# Here we give our VMs an prefix for name which is called in my case "W2K8R2-T" +  counter number = a.e. W2K8R2-T1

# Default VM RAM setting = 1 GB RAM

# Default vCPU setting = 1 vCPU

New-VM -name $vmname -Path ("V:\"+$vmname)
# Now here we call the powershell commandlet "NEW-VM" and point to my drive V:\ where the VMs should be created

Copy V:\Master\MASTER_R2.vhd ("V:\"+$vmname+"\"+$vmname+".vhd")
# here we duplicate (copy) the master-VHD to the destination drive (source -> destination)

Set-VM -vm $vmname -bootOrder @(2,1,0,3)
Set-VMMemory -vm $vmname -memory $vmram
Set-VMCPUCount -vm $vmname $vmcpu
Add-VMNIC $vmname
Set-VMNICSwitch -vm $vmname -nic (choose-vmNic $vmname) (choose-VMswitch 0)
Add-VMDrive $vmname 0 0
Add-VMDisk $vmname 0 0 ("V:\"+$vmname+"\"+$vmname+".vhd")
# add disk which we had copied earlier to the VMs configuration

Add-VMDrive $vmname 1 0 -DVD
Start-VM $vmname
sleep 30

Now we can go and take us a loonnng break ;-) as the copy time of the MASTER-VHD (depends on size of MASTER.VHD) does take the most of the runtime of the script. My recommendation here would be to use dynamic disks but of course this depends on the performance requirements of disk I/O for these VMs.

PS: Of course there is room for improvements but this blog/script should “only” give you an idea how the powershell library can be used and with your own creativity there is really no borders for creating a customer friendly solution :-)

If you have any further questions please let me know.