Technology Solutions for Everyday Folks
Typos Happen

Auto-Generate OSD Computer Name

Last summer while re-designing and upgrading our primary task sequence for the "multi-user devices" in our fleet (computer labs, learning spaces, etc.), I decided to tackle what had become a bit of a perennial problem: device naming.

Background

The vast majority of our multi-user devices receive an annual refresh ("wipe and load"), often during late July or early August before faculty return to campus. This allows us to "reset" the devices to a common state, address configuration drift, address any hanging software/firmware updates, and so forth. A few years ago I developed a common multi-user task sequence to provide a customization/configuration as necessary per use case/space, and it changed everything for us. Little needed to be known or understood by our techs to successfully [re-]build or deploy these machines, and as such it significantly reduced the time commitment since most things were baked into the task sequence.

Except things like addressing the machine name(s) and machine use case (or location).

Four paragraphs in, this post explains the former situation (naming). I'll explain the latter (use case) in a different post coming soon.

Naming Scheme

My campus is one of five across a statewide system, and because I don't pretend to manage enterprise systems better than the real pros in our institution I like to play along as much as possible. In addition to many other things, this means is I need to ensure our devices not only have a unique name in our campus fleet, but also said name must be unique within the entire enterprise. Years ago I "designed" the naming scheme we use today, and it distills to this:

{CampusAbbreviation}{ModelNumber}-{7DigitIdentifier}

Where:

  • CampusAbbreviation is a unique identifier for our subset of the enterprise fleet, exactly three characters in length (e.g. "MNS" for Machine Name Sample);
  • ModelNumber is a device's model number, exactly four digits/characters in length (e.g. 7060 for a Dell Optiplex 7060); and
  • 7DigitIdentifier is a unique component of a device (portion of a serial number or Dell service tag, e.g. 1GX54Z2), exactly seven characters in length.

The example noted above would necessitate the unique machine name with exactly 15 characters: MNS7060-1GX54Z2

The Problem

Ultimately, human interaction causes the problem of having a bad machine name here and there. Situations abound with "fat fingering" or typos, misunderstanding the naming scheme, or transcription errors (is that an O or a 0?). While there are ways to (manually) correct the problem, I had the simple thought:

What if we automated the naming process and removed the step?

I hadn't originally bolted anything like that into the task sequence since it wasn't generally an issue when we had just a few techs performing the action. As the scope grew, we had more techs with less familiarity running around, so the additional complexity originally avoided was causing more (manual) fixes to be applied.

The Simple Solution

Since we're a 100% Dell shop with regard to our multi-user fleet, save for n=few macOS boxen which are managed in a different manner, I figured I'd just whip together a few lines with our friend Powershell and pull the information from WMI. This would automatically and programmatically build the unique machine name and virtually guarantee its correctness. An added bonus: it saves a boatload of tech time in the aggregate and lets them get to their next task earlier in the process.

$tsenv = New-Object -COMObject Microsoft.SMS.TSEnvironment
$tsenv.Value("OSDComputerName") = ""
$tsenv.Value("SMSTS_DellMachineNameGenerated") = "False"

$Prefix = "MNS"
$Make = (Get-WmiObject Win32_ComputerSystem).Manufacturer
$Model = (Get-WmiObject Win32_ComputerSystem).Model
$ServiceTag = Get-WmiObject -Class Win32_BIOS | Select-Object -ExpandProperty SerialNumber

If ($Make.StartsWith("Dell", $true, $null)) {
    # We only want the numeric part of the machine model
    $ModelNumber = $Model -replace '\D+(\d+)', '$1'
    $tsenv.Value("OSDComputerName") = $Prefix + $ModelNumber + "-" + $ServiceTag
    $tsenv.Value("SMSTS_DellMachineNameGenerated") = "True"
}

Voila! Works every time! I'll also note that this script assumes a Dell make and certain type of model, which is why I don't have any hard logic to limit character counts as our situation doesn't introduce any unexpected model types (our multi-user fleet generally spans six similar models). I would need to add a couple of additional bits should I expand this to our greater fleet.

The task sequence(s) in question will still present the default (old) machine name dialog we've been using forever if the variable SMSTS_DellMachineNameGenerated is False, which allows us the ability to address any one-offs without adding complexity to the base script above. If I knew we'd have more than a few other makes (e.g. HP, Lenovo), I'd bolt in appropriate logic as necessary.

For distribution, I have the production script included in a "toolkit" package referenced by the task sequence. A task sequence step to Run PowerShell Script makes reference to said toolkit package and invokes the Powershell script.

The solution is super simple, incredibly effective, and has more or less completely eliminated all manual adjustments this academic year.

Hopefully you find it interesting and/or useful. Feel free to steal it from my GitHub repo or fork/improve as you see fit!

Headline photo via Giphy