Gather No More – Using Dynamic Task Sequence Variables in ConfigMgr


Update 09/14/2020 - You can download the Gather Light Task Sequence from the Community Hub now! https://communityhub.microsoft.com/item/7812



Update 02/21/2020 - I added a new section with a Gather Task Sequence. Check out the DIY Gather in the Task Sequence section below. It even has a GIF (unlike Software Center!)


If you’ve used the Microsoft Deployment ToolKit (MDT) or ConfigMgr or have ever heard of ‘Johan and Mikael’, you’ve likely used or at least heard/read about using MDT and the Gather script that’s included with it as part of your Task Sequences. We have always included some form of MDT in our Task Sequences but I’m in spring cleaning mode and it’s time to start some re-work on our main OSD Task Sequence now that we have completed our Windows 7 upgrade project. Now’s the time to see if I can replace Gather with native ConfigMgr Dynamic Task Sequence Variables.

Gather Alternatives

If you actually still think you need Gather after you finish reading, here are some community tools that can at least help you move away from using the MDT scripts.

All of these work and it’s really just a question of what you need to Gather.

Dynamic Variables

I believe Mike Terrill once told me about these variables (He also drives a fancy Tesla) and while they are missing a few key items, they can get the job done. In order to create these variables, you need to add a Set Dynamic Variables step to your Task Sequence. When this step runs, it will populate a set of commonly used variables. Here’s a link to the doc https://docs.microsoft.com/configmgr/osd/understand/task-sequence-steps#BKMK_SetDynamicVariables. This link also contains instructions for using the Set Dynamic Variables step. It is a very powerful step with lots of functionality.

As you can see from the list, it’s not nearly as many variables as you’d get with MDT Gather, however, I have found that I generally only need 5 - Make, Model, SerialNumber, IsVM & IsLaptop. I know others will need more, but that’s it for me and I’ll explain how I use next.

On and in case you’re into scripting things, there are 4 PowerShell cmdlets to manage the Dynamic Variables steps.

Use Cases

To use these Variables, you can simply refer to them like any other variable like: %_SMSTSMake%. Here are some of the places I use these variables:

  • Computer Naming
    • We have a wizard that sets the site code based on the device’s gateway then I append the site code to the serial number like %SiteCode%-%_SMSTSSerialNumber%. * There’s a challenge with the serial number here that I’ll cover in a moment.
  • IsLaptop & IsVM
    • We target specific software (VPN) to Laptops VMware Tools to VMs.
    • All of our laptops are either Lenovo Thinkpads or Microsoft Surfaces. I will replace IsLaptop with _SMSTSModel like *Thinkpad* and _SMSTSModel like *Surface* and it should be a pretty simple swap. I believe we only use IsLaptop on a single step in Task Sequence.
    • All of our VMs are VMware, so I can simply swap IsVM for _SMSTSMake -like *VMware* for the 2 steps where I was using it.
  • Drivers & Bios

A Square Dozen Image

A Square Dozen Image

A Square Dozen Image

Serial Number Gotcha’s

The only downside that I’ve found so far with this approach is that hardware manufacturers don’t care about how we use serial numbers.
Dell, Lenovo and HP seem to have reasonable formats, but VMWare and Microsoft make you work for it.

VMWare uses this craziness:
VMware-42 15 8d a3 7c b6 f6 ba-d9 90 40 60 11 ed f3 13

Microsoft uses 12 digits, the last 4 of which are common across devices in the same model. Not to mention that all of ours so far start with `` or 00 which makes dropping a list of them into Excel more difficult than it should be.

To handle these, I can’t just append my 2-5 digit site code plus - to the serial number or it blows things up. VMWare is pretty obvious, Microsoft’s is more subtle. Active Directory only supports 15-character computer names, and (someone on the internet told me this) doesn’t really like all numeric numbers. While Windows doesn’t seem to care if you go over 15 characters, Active directory will hate you, and you will hate whoever at Microsoft came up with their serial number system after having your Task Sequence repeatedly blow up on the domain join step over and over and over again! (I’m not bitter).

All that said to say, for VMWare, you’ll want to drop the VMWare part and remove the spaces to create a clean serial number that you can work with. go from
VMware-42 15 8d a3 7c b6 f6 ba-d9 90 40 60 11 ed f3 13
to
42158da37cb6f6bad990406011edf313

So now you’ll have a really long serial number for VMware and an almost-too-long-in-some-instances serial number for Microsoft.

The next step is to truncate them. For VMware, I have had good luck just taking the last 8 characters. For Microsoft, I use the first 8 (since the last 4 aren’t unique anyway, it doesn’t matter).

So, here’s a simple script that I’ve been using to take care of all of this:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
$WMIBIOS = Get-CIMInstance -Class win32_BIOS
$WMIComputerSystem = Get-CIMInstance -Class Win32_ComputerSystem

$Manufacturer = $WMIComputerSystem.Manufacturer
$SerialNumber = $WMIBIOS.SerialNumber

If ($Manufacturer -like "*Microsoft*") { #trim the trailing 4 chars since they are the same across most models. Per Microsoft...
    $CharsToTrim = $SerialNumber.Length - 8
    $SerialNumber = $SerialNumber.Substring(0,$SerialNumber.Length - $CharsToTrim)
}
ElseIf ($SerialNumber.Length -gt 8) {
    $CharsToTrim = $SerialNumber.Length - 8
    $SerialNumber = $SerialNumber.remove(0,$CharsToTrim)
}
Return $SerialNumber

Simply drop the script into a Run PowerShell Script step in your task Sequence and set the output to a new variable name. Now, you could remove all of the lookups and just pass _SMSTSMake and _SMSTSModel to the script or use them as Options on the steps, but keeping it all in one simple script makes it easy to re-use later.

A Square Dozen Image
]

DIY Gather in the Task Sequence


Update 02/21/2020 - Ok, so I thought about this some more and decided that I would see if I could just make a Task Sequence as a module to perform all of the gather steps directly in the Task Sequence instead of using external scripts. At this point, we’ve moved from one custom solution to another and kind of missing the point of ‘going native’ but in any case, conceptually, you could make a stand-alone child task sequence that performs all of your Gather steps then just call it from any other Task Sequence as needed.


There’s a link at the end where you can download Gather Task Sequence content from GitHub. Here are some pretty pictures and scripts

Main Folder for Gather to make it ‘portable’. Just copy the folder where you want or put in a child TS.
Main Folder for Gather to make it 'portable'. Just copy the folder where you want or put in a child TS.

Setup the variables with default values just to keep things clean.
Setup the variables with default values just to keep things clean.

Run a script using the %_SMSTSMake% variable as a parameter to get the serial number
Run a script using the %_SMSTSMake% variable as a parameter to get the serial number

Get the serial number
Get the serial number

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
Param (
    [String]$Make
)
$BIOS = Get-CimInstance -Class Win32_BIOS

$SerialNumber = $BIOS.SerialNumber.Replace(' ','')

If ($Make -like "*Microsoft*") { #trim the trailing 4 chars since they are the same across most models. Per Microsoft...
    $CharsToTrim = $SerialNumber.Length - 8
    $SerialNumber = $SerialNumber.Substring(0,$SerialNumber.Length - $CharsToTrim)
}
ElseIf ($SerialNumber.Length -gt 8) {
    $CharsToTrim = $SerialNumber.Length - 8
    $SerialNumber = $SerialNumber.remove(0,$CharsToTrim)
}
Return $SerialNumber.ToUpper()

Script to look up chassis types from WMI and output a clean name to use.
Script to look up chassis types from WMI and output a clean name to use.

Default is NoChassisTypeDetected. You’ll see this for VMware and likely other VMs.
Default is NoChassisTypeDetected. You'll see this for VMware and likely other VMs.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
$Laptop = @(8, 9, 10, 11, 12, 14, 18, 21, 30, 31, 32)
$Desktop = @(3, 4, 5, 6, 7, 13, 15, 16, 35, 36)
$Server = @(23, 28)
$CIMChassisType = (Get-CIMInstance Win32_SystemEnclosure).ChassisTypes

$ChassisType = Switch($CIMChassisType) {
    {$Laptop -eq $_} {"Laptop"; break;}
    {$Desktop -eq $_} {"Desktop"; break;}
    {$Server -eq $_} {"Server"; break;}
    default {"NoChassisTypeDetected"; break;}
}

Return $ChassisType

Setting the Gather variables based on the values we found.
Setting the Gather variables based on the values we found.


UPDATE 02/24/2021 - If you use Surface Pro 7+, you will need to update your Gather step to look for Surface Pro 7+ and set IsLaptop = True. This is due to the ChassisType being set to 1 instead of 9 on these devices. This is expected to be fixed at some point, but if you have an immediate need, here’s the fix.


Fix for Surface Pro 7+
Fix for Surface Pro 7+

Echo out the values to the command line so that they show up in smsts.log.
Echo out the values to the command line so that they show up in smsts.log.

1
cmd /c echo "ChassisType: %ChassisType%" && echo "IsVM: %IsVM%" &&  echo "IsLaptop: %IsLaptop%" && echo "IsDesktop: %IsDesktop%" && echo "IsServer: %IsServer%"

A gif using Task Sequence Debugger to show how the variables get set!
A gif using Task Sequence Debugger to show how the variables get set!

SMSTS.log output showing the variables that got set by Gather
SMSTS.log output showing the variables that got set by Gather

As you can see, it takes a few steps, but it’s not that hard to add other variables to this and use it as a master variable setting Task Sequence that you reference in other Task Sequences. Is this the most efficient? Not likely? Does it reduce the need for custom code? Maybe? Does it require any extra contents/scripts? Nope. Anyway, I feel like this completes the picture just a bit more.

Click HERE to download the complete Gather Task Sequence from my GitHub repo. Or Download it directly from the console in the Community Hub https://communityhub.microsoft.com/item/7812.

That’s all Folks

As you can see, the built-in dynamic variable can be a decent replacement for Gather if you don’t have hugely complex steps in your Task Sequence. It just takes a bit of planning. If you are starting fresh, this should be easy. Just build your Task Sequence with the dynamic variables and if you get stuck or need more variables, go grab one of the community tools and go to town.

Ultimately, I’m not saying you SHOULD use any way over another, I just want to highlight that you COULD reduce your content overhead just a little bit by using the built-in variables.


This post is dedicated to Ari Saastamoinen who constantly badgers me to write things for him and I finally gave in.