2012
11.20

A friend of mine works for a software company, looking after a test rig for one of their product families.  The test rig is based on Hyper-V, and they have to frequently provision lots of virtual machines to test new products.  We were chatting about how they do this a few weeks ago and I thought “I bet I could do that using PowerShell, and I bet I could create a very nice solution too”.  What I wanted: A PowerShell script that would make lots of Windows Server 2012 (WS2012) Hyper-V VMs from a comma separated values (CSV) file.  I also thought that this would be a great demonstration of PowerShell during WS2012 Hyper-V demos that I’m frequently doing.

So I put some work into it.  The concept is based on a previous script that I wrote, but I took it to the Nth degree.

Here’s how my script works:

  1. You create a CSV file that specifies the configuration of each VM (1 row per VM).
  2. You edit the script to read that file (easy change near the top)
  3. You run the script
  4. The results are recorded in a log file that you specify in the script (a second easy change near the top)

I’ve put instructions in the script.  I’ve also supplied a sample CSV file in the zip file to show three different types of VHDX creation.

The script allows you to specify the following in the CSV:

  • Storage location of the VM
  • Name of the VM
  • Processor count
  • Virtual memory, including Dynamic Memory if you want
  • VHDX type and configuration, including Fixed, Dynamic, and Differencing

So how could you use the script?

  • Maybe you want to create lots of pooled or personal VMs
  • Possibly you need to deploy a demo lab with lots of VMs
  • Maybe you are like my friend, working in a large software test environment, and you’d like to deploy lots of VMs, and you’d like to be able to vary the specification and build of those VMs

There’s nothing to stop you from editing the script and either adding/removing functionality.  If you find it useful, then go ahead and use it.  In fact, if you do use it, then tell me how because I’ll be interested.

This script is not supported by me.  Use and/or modify the script at your own risk.

Please note that this script is mine and you may not re-share it without my permission.  Please link to this blog post instead.

You can download the script and sample CSV file from here.

Possible improvements:

  • Add remote host functionality
  • Add cluster functionality
  • Start VMs

This information has been brought to you by Windows Server 2012 Hyper-V Installation and Configuration Guide (available on pre-order on Amazon) where you’ll find lots of PowerShell like in this script:

image

6 comments so far

Add Your Comment
  1. I’ve done this with XML file and powershell for my demo-lab. the xml includes the needed vm config with network configuration and the script mounts an unattended iso for server 2012 to the vms. i can set up my needed lab with an basic server installation for all vms fully automatic. very time-saving and helpful :) like this blogpost – good job

  2. Is there a way to create VMs based off a single image where only the differences between each VM and the image are stored? In the VMware world, I think Orchestrator does this for VMs by creating a “golden image” and then spawning VMs based on that image. The advantages include less storage required and the ability to patch the golden image and all VMs get patched.

    • That’s a differencing disk. However it’s only intended for things like testing or pooled VDI where the VMs are short-lived. You can’t patch a differencing disk’s parent VHD/X … you have to tear down the VMs, replace the parent with a patched version, and start over.

  3. Hi Aidan,
    A very big thanks for this script, you just made my day (night actually), once more!
    i’m teaching a WS2012/W8 crash course, and this script will be featured tomorrow to my students (directly from your blog that is!)…
    best regards, and a big thanks once again.

    Pierre.

    • Thanks Pierre! You just made my night too :)

  4. Optimizations :)

    PS C:Temp> if(1MB -eq 1048576) {Write-Host “So 1MB is in fact” (1MB)}
    So 1MB is in fact 1048576
    PS C:Temp> if(1GB -eq 1073741824) {Write-Host “And 1GB is” (1GB)}
    And 1GB is 1073741824
    PS C:Temp>

Get Adobe Flash player