How to provision 500 VM’s. Fast.

The Challenge

Back around March 2010, I was asked by Stephen Spellicy, who was on the vSpecialists technical marketing team, to help out on a project he was doing for EMCworld 2010. I drove up to the Nashua lab and sat down to help. Stephen told me about this new cool product coming out from EMC called VPLEX. He wanted to create 500 VM’s and he was going to show VPLEX vMotioning those systems from one datacenter to another. Oh, and Pat G. and Chad were doing to do it live on stage. Yea, no pressure.

So, the challenge to me was “Can you create a script that creates 500 VM’s?” Hell, that shouldn’t be too hard, even for a coding moron like myself so I responded with “I can write a Powershell script for that!”. And off I went…

Why Powershell?

You see, I suck at writing code. I’ll never be the guy who comes up with some seriously whacked algorithm that does amazing things with 5 bytes of code. Being a former IT guy, I think in tasks. This task was “Create 500 VM’s, each with a unique ID.”

Powershell was designed for that in mind. It takes the best of a number of IT Admin CLI’s. There’s bits of Bash, DCL and others mixed in there. It’s designed to get stuff done, with a minimum amount of hassle. Is it something I’m going to write an enterprise SaaS app in? Of course not. But for IT tasks like “Create 500 items using this template”, it’s damned near perfect.

The History of the Script

So, my first stab at this, before other requirements started coming in, was pretty simple. Ten or so lines of code. Read in from an Excel generated .CSV file the name of the VM’s and a foreach loop to create the VM’s asynchronously. But this presented a bunch of limitations. There was only one host and datastore defined. Naturally, that wasn’t going to cut it.

Version 2 took this a little further. Still the same limitations but it named the VM’s based on a count. e.g. DEMO_VM_1, DEMO_VM_2, etc… so I could dump the .CSV file and just use variables to control how many VM’s. But still, I needed to space out the VM’s being created across a number of hosts and a number of datastores. The script needed to be more adaptable.

Around this time, I started recruiting my friend Alan Renouf (@alanrenouf) to help me in this. I was rapidly reaching the need for a lifeline. Alan helped me with a few of the concepts and re-wrote some of the code to make it run better.

Version 3 took on a whole other look and feel. First, we created a unique template on each datastore. This way, when we were creating from template, we weren’t overtaxing the template datastore with IO requests. Next, we added a bunch of datastores and hosts and dumped them into arrays we could pull from.

Next, we added some code for generating randomness of the VM name so it wasn’t all done serially. We still used a standard prefix as an easy way to distinguish the VM’s from others.

Now, here’s where it got fun. I was reading a blog post from Luc Dekens (@lucd) on the Get-Task cmdlet and async tasks. I create a hash table of New-VM tasks This allows me to keep the pipeline of tasks going. As a task finishes, another task starts. It was VERY helpful.

Version 4 was mainly a cleanup and tweak. I used Luc’s code twice. Once for creating the VM’s and managing that process and second for starting the VM’s in a balanced fashion. Sure, I could have just said “Start-VM {list of VM’s}” but Luc’s code would start each one and monitor for success before starting another. This was much smoother.

The Result

The script would create 500 VM’s in a matter of minutes. It worked really well. And then Nick Weaver (@lynxbat) got a hold of it and tweaked it some more. (I’d still like a copy of that script Nick!) At EMCworld, I ran into Alan and Nick and told Alan that the code he helped with would be used for the big EMCworld Pat G/Chad demo. His response? “Crap, had I known that I would have done a better job!”

At the end of this, Stephen was happy and had christened the script “The Baby Maker” and called Alan and I “the proud parents”. I was ok with it up until the parents part. hahaha


So, I’m presenting my copy below. It’s quite functional and all in about 60 lines of actual code. If you need to create a BUNCH of VM’s, maybe for testing or benchmarking, this script will do it quite quickly. Use the code at your own risk. EMC and I are not responsible for you causing the end of mankind because you ran it. Oh, and batteries are not included.

Cleaning up

Ok, you’ve just created 1000 VM’s and you’re thinking “Dammit Foley! How do I get rid of all of these VM’s quickly before my boss finds out!” Easy Chief, I’ve got you covered. Below is the Remove-VM’s script that uses Luc’s code, again, to troll thru the VM’s, create a hash table and delete them.