Last week I had the distinct pleasure of getting to speak at the VMUG UserCon events in both Seattle and South Florida. My goal in both of these speaking slots was not to do the typical vendor sales pitch, but provide some good solid information to the community that could be taken back to attendees’ locations and be put to good use. The topic I chose is a popular one in the industry right now. I wanted to talk about automation, with one PowerCLI Script I put together in mind.

The Story

In a previous job, I was in charge of managing a fairly large vSphere implementation that housed the hosted-private-cloud practice of a managed services provider and hoster. This environment, while it ran good, always challenged me to find ways to further optimize deployment processes. Each on-boarded customer had a couple of things in common. They all wanted AD, and they all needed file hosting. I wanted to incorporate those needs into the VM deployment process to ultimately save on time. Sadly, time was in short supply to come up with a script at the time. Now that I work for Altaro, and one of my primary duties is coming up with community focused content, I finally had the chance to come back to this issue, and tackle it. My goal was to solve this issue, and share the solution with the community.

Technical Goals of the Script

  1. Must be FULLY automated from the moment you hit the enter key to start the script.
  2. Must provide verbose information for the administrators viewing if desired.
  3. Must Deploy 2 VMs from pre-existing templates and customization specs.
  4. Must customize each virtual machine according to the specified customization spec.
  5. Must be able to define static IP addresses.
  6. Must configure AD on one of the new VMs and provision a new AD Forest.
  7. Must create a new custom administrative account within the domain.
  8. 2nd VM must be automatically joined to the newly defined domain.
  9. File Services must be installed on the second VM
  10. A new SMB share must be defined on the file server VM, once the file services role is present.

This is certainly a lot to get done with a single press of the enter key, but it is doable. Also, this is likely just the beginnings of a new environment, but the script could very easily be modified to deploy more than just the two VMs.

Community Goals of the Script

I’ve always enjoyed giving back to the IT community that has helped me so much throughout my career, and I really wanted to that with this script. My goal from a teaching aspect with this script was to be the follow:

  1. Well Documented and Heavily Commented
  2. VERY sequential ordering of the commands, as to be easy to follow for beginners
  3. Best Practices definition of variables at the top of the script.
  4. Well segmented so that certain sections can be copied and duplicated if desired.

While the script was very well received at the VMUG events, I was asked by some of the more tenured PowerShell folks as to why I didn’t use any functions or more advanced formatting. The main reason was number 2 above. I’ve found that IT Pros have a very sequential line of thinking when it comes to completing tasks. I wanted to script to be done in a very….  step 1…. then step 2….  then step 3, type of fashion. This way it’s easier for a PowerShell beginner to see how the script works, and take the bits and pieces that they need for their own scripts. Functions and some of the more advanced techniques can be more difficult to follow if you’re not used to PowerShell.

The Secret Sauce

The first half of the script simply consists of setting variables to be used later in the script’s execution. Once the actual task completing commands start being called, there are a number of basic cmdlets being called to complete most of the functions. If I had to pick some of the most important cmdlets for this script they would be the 3 below

Wait-Tools: While nothing really special, this is an immensely helpful cmdlet. I call this cmdlet several times throughout the script. What Wait-Tools does, is it targets a VM, and waits until VMware Tools within that Guest VM is in a responsive state. This is especially useful for reboots, where you don’t want to script to continue until VMware Tools within the guest is working. In most cases all other services in the VM will be up and running once tools is functioning, however there were a couple of times in the script where I had to follow this up with a Start-Sleep cmdlet to give the OS just a little extra time to come online before continuing.

Get-VIEvent: Like the above, Get-VIEvent is not overly special by itself. However, When paired with other commands and some filtering options, it can become quite powerful. I used this cmdlet in a loop fashion in the script to scan the vCenter logs to look for various VM customization events. This logic allows the script to wait until the guest customization of the first VM is completed, prior to trying to make any changes to the OS contained within the VM.

Invoke-VMScript: If you can only take away one useful command from this post, choose this one. This cmdlet, in a word, is awesome. This single cmdlet allows your script to reach into the guest operating system, and execute a block of code. This is how all of the OS level changes are done throughout the script. It takes care of things like the installation of AD, and the configuration of the new file share on the file server. It completes this task by pushing the codeblock to the VM via VMware Tools. So the only thing that is needed for this is for tools to be in a running state inside of the target VM.

See it in Action

I’ve annotated the below video to show the script in action. Be advised, that the script actually takes 20 to 30 minutes to run in the below state. This video has had quite a bit of the wait periods removed so you can see the script function in it’s entirety.

 

 

 

 

 

 

 

 

The Script

So here is the part you’ve been waiting for. Below is the script. Take it! Use it. Learn from it. This is simply one of my humble contributions back to the IT community.

Again the script is heavily self-documented and commented, so you should be able to read through it and set the needed variables as needed. Note, all of the user-definable variables are at the top of the script.

 

Summary

There you have it! It is my hope that this will be of some use to you, whether that be helping you get a task done at your job, or helping you learn how to use PowerShell and automate.

If you have questions, feel free to use the comment form below, and I’m looking forward to seeing if this script was useful to you.

Enjoy!