Tuesday, January 29, 2013

Imaging a large number of labs with WDS and PowerShell

In a previous life, I worked for a university that was broke. Not broke in the sense that it was falling apart, but broke in the sense that we had to make a lot of our own tools. This meant no SCCM, no Ghost (does anyone even still use it?), etc. There are dozens of labs and had a clunky imaging solution that we rolled ourselves based on SQL Express, VBScript, and WinPE distributed by PXE Linux on a CentOS box. Certainly a very clunky scenario. When I was made the lead on the campus-wide Windows 7 rollout, I knew I needed to get a fresh start on this.

To capture or not to capture?
One of the great religious battles of our day (as far as desktop imaging goes) is whether or not capturing a reference image and sysprepping, or deploying a standard "thin" image and installing the necessary applications through another means is the best way to go.

The majority of people capture thick images with preconfigured profiles and software.

I'm firmly in the thin image camp. Not having to deal with sysprep, reams, capturing, and maintaining multiple reference images is a major win for me. Also, not having to update the image every time a single piece of software in it needs a version bump is certainly a good thing. In my experience, admins responsible for client OS deployment tend to be on the more entry-level side of the curve (certainly not always, though). These admins generally have weaker scripting skills, but let me assure you - learning to script your installations might be more burdensome early on, but it will save you a lot of hassle later.

To properly roll your own thin images without something like SCCM, you will need to be familiar with dism and scripting. If you're not familiar with either, you're about to get a crash course.

The Script

Let's break it down bit by bit.

First of all, there was a legacy requirement that crushed my soul that each lab computer have a static IP address whose last octet matched the PC number. So, if there was a computer in building A, room 101, and it was the 20th PC, the name would be A101-PC20 and it's IP might look something like That's what the Set-IP function that I borrowed from poshcode.org does. It takes the network segment, the gateway, and the subnet mask, and sets the appropriate static IP. The switch statement later on sets the $pcNumber variable that is used in the last octet of the address.

Since all of these computers are staged in WDS using the netbootGUID, the computer is already named at the time this script is called from the unattend.xml file. All computers in a lab have a hyphen in them. All computers that are in standalone classrooms do not. This makes it easy to use a line like $isInLab = $name.Contains("-") because it will return $true if the machine has a hyphen in the name, which makes it a lab computer. If it's a lab computer, we're going to split the name into an array called $nameSplit which has the first element set to the lab name and the second element set to something like PC20. From there, we can split the 20 out of the name and use that in the last octet of the IP address. We'll use the name of the lab in a second.

The final block of code basically says that if a machine is in a lab, call the function to set the static IP address and then call a batch file on a server that has the scripted installations for all software in that lab. So, the batch file is named the same as the first part of the computer name that we split out earlier. This means that we can use the same unattended file and the same thin image, but have different sets of installed software per lab. If it's in a classroom, then it will get a default set of classroom applications that are on all classroom podium computers.

Sure, MDT can do all of this, but it seemed like a sledgehammer for a nail in my case. Sure SCCM can do this (and it can do it better), but there was no money for it. I got by with vanilla WDS, PowerShell, and batch scripting and it worked just fine for years. As far as I know, this is still the process being used to image the labs there, even though I'm long since gone.

Remember, don't be afraid to make your own tools!


  1. Cool. I like WDS. The only thing I don't like about WDS is getting those unattend answer files just right. And having to inject drivers into the images pre-2008R2. I love this kind of automation.

    1. Yeah, the unattended files can be daunting the first time, but once you have a good reference unattend, it's really just tweaking the OOBE fields.

  2. We use A product called Smart Deploy combined with WDS for mass deployments.