Recently I had a Client who wanted to control the naming of their devices during the build cycle in OSD during New, Replacement and Upgrades scenarios, they also wanted to specify a User Device Affinity for some but not all devices. The mechanism had to leverage an initiative that was physically asset tagging all their devices and at the same time entering the tag into the devices SMBIOS. With all new devices being tagged like this on arrival, it meant a reliable relationship between the Asset Tag and a Device’s Name could be established and controlled.

The Client couldn’t of asked at a better time, John Vintzel from the ConfigMgr Product Team had blogged recently touching on the key elements needed to do this very task!

All I needed to do was have a control file containing the relationship data, which I call below the Asset Check Repository, and some VBScript to glue the processes together to A) identify the Asset Tag, B) locate a matching Tag in the Repository along with UDA if specified, and C) push these values into the appropriate Task Sequence Variables for the remaining Task Sequence steps to be processed.

I thought I’d finesse the mechanism a bit more then share with the community as its a cracking way to manage device naming and applying User Device Affinities within OSD.

Once you have your estate setup with SMBIOS Asset Tags, and have an entry in the Repository for each of them, you’ll be able to do BARE, REPLACE and UPGRADE builds while reusing the same device name, and managing any defined User Device Affinities so that Applications can be preloaded.

There are a couple of ways you can implement this yourself, the script instructions on how to set it up are below. It’s a long read but pretty much all my field notes and ideas are there. Enjoy and let me know if you get it working.

The format of the guide, was a bit freestyle, I just quickly built it up and tacked detail onto it in one sitting, so excuse me if it goes astray or I’ve missed something, I’ll edit the source post on Rob Marshall's WMUG blog as I see typo’s and add new content, I usually read it a few days later and tut, but I’m looking to update this mechanism, so a rewrite is inevitable!

Asset Check Script Features

I added in the ability to do automatic device naming, so, if the asset tag is found in the SMBIOS but not in the Repository it’ll continue and give the device a temporary name based on a prefix (currently set to TMP in the script) and the identified Asset Tag. These can then be seen in a ConfigMgr Collection with a query looking for the device name prefix (TMP% !), their Hardware Inventory will return the Asset Tag and you can then enter that into the Repository so it is named correctly at the next rebuild, hopefully creating a closed loop to capture any devices not in the Repository.


To toggle automatic naming, just edit the AssetCheck.vbs script and use TRUE (on) or FALSE (off) as highlighted in the screenshot above

If Automatic naming is disabled, custom errors are returned to indicate where in the process the error occurred:

9997 -  Error setting the Task Sequence Variables

9998 – No Asset Tag Match in Repository

9999 – No Asset Tag found in SMBIOS

These can be viewed in Reports or in the SMSTSLOG.

Download the Asset Check Script

You can download the zipped AssetCheck.vbs file here from the WMUG website

So how do I configure my SMBIOS Asset Tags?

This is so out of scope it’s on another planet, no joking aside there are several ways to configure your SMBIOS settings but really this should be driven by some kind of device branding scheme, associating a devices physical Asset Tag with the SMBIOS digital Asset Tag. Ultimately somehow you need to do this association, physically or remotely, you’re going to need to figure out how to brand your existing estate.

The BIG ask - Asset Check Script - PowerShell or VBScript?

Put simply, when PowerShell is, by default, in all environments, as is VBScript, I’ll switch over to it completely, but we’re not there yet, almost, but not quite.

For ConfigMgr, we won’t get support for PowerShell in WINPE until ConfigMgr SP1 releases, this is because SP1 brings WINPE 4.0 support, which comes with WADK, and finally gives us .NET 4 and PowerShell packages which we can install.

The .NET and PowerShell WINPE 4.0 packages are not installed into any boot images by default, as is VBScript, hence why I feel PowerShell is not yet pervasive enough to replace VBScript entirely, and completely dominate engineering environments.

Eventually, PowerShell will become my scripting tool of choice, for all of my automation tasks, and if I was to take a stab at when this would be I’d say tail-end of 2014. By then I’d expect most people flitting through my guides to have PowerShell across their entire estate top to bottom, induced by OS upgrades (Win8, W2012), product upgrades (ConfigMgr SP1 for WADK, WINPE 4.0) and installing PowerShell onto older OS’s such as Windows XP, Windows 7 and Windows Server 2008 R2.

I saw the same take-up and switch-over debates when VBScript was announced. It took a long time for us to move off of custom MSDOS boot media such as Floppies, CDROMS, we held out for a long time, but eventually Microsoft pushed us forward and into 32-bit bootable environments where VBScript could be run at will, which ultimately lead to almost complete adoption in engineering teams as the scripting tool of choice. I saw estates running a mix of stuff such as Kix95, MSDOS Batch and VBScript, and seeing growth of VBScript adoption grow and eventually it became dominant, and now the same cycle is repeating for PowerShell.

We’re almost there, modern Microsoft Operating Systems have PowerShell installed by default, and it can be retrospectively applied to older operating systems as well as our engineering tools becoming PowerShell ready; Quite a few environments are ready now, but not all are, and this is why the guides script was written in VBScript, for the majority to implement.

I left out a lot of boot media history there, at the very least I should make a token nod at Barts boot disk amongst many others.

Invoke Asset Check during Pre-start or Task Sequence?

The Asset Check script can be invoked from a pre-start command in boot media, or via a Task Sequence Run Command Line step.

We’ll choose the latter, Run Command Line.

It’s entirely up to you where you locate the Asset Check scripts execution, both have advantages and disadvantages, both produce the same result, execution, we sure are lucky to have options!

The Asset Check Repository

Asset Check depends on the Repository being accessible during execution of the Task Sequence. The file itself is simply a three column (no header) CSV, here is an example

Asset Tag Machine Name User Affinity – UDA
123456789A ,LON123456789A CONFIGMGR\ConfigMgrUser

Here is a live AssetRepository.CSV file that I used in my lab during the creation of this guide


The Asset Tags in the above example come from Hyper-V 3.0, my test machines are called BUILDA, BUILDB, BUILDC, and I have a single user defined for UDA testing, ConfigMgrUser

Wherever you store your Asset Check Repository, you’ll need to maintain it, and depending on if you implement this at the start of OS deployment or after the deployment has taken place, this maintenance will be frequent or occasional.

Adding, removing and amending entries is pretty easy, just open the file and make the edits, there is only one rule and that is that if no UDA is required that you still include the comma

The following is valid notation:

Asset Tag,Device Name,SMSLAB\User

Asset Tag,Device Name,

The following is invalid notation (missing the comma):

Asset Tag,Device Name

Where should the Asset Check Repository file reside?

The Asset Check Repository file, a 3 column CSV file, can be stored alongside the Asset Check VBScript in a ConfigMgr Package, or it can be stored on a Network Share.

Using a Network Share


  • The Repository is centralised, and made available to the Asset Check script over the network
  • The Repository is not spread out between engineering script locations, the ConfigMgr Package source location and any or all Distribution Points
  • Changes can be made to the Repository on-the-fly, the meantime between edits and execution is immediate


  • Storing the Repository on a Network Share is not scalable in an Enterprise environment. For the next version of the script I’ll make the Network Share configurable as a script parameter so that it is.
  • The Share permissions are topical, the script is currently not configured to map a network drive under a domain users credentials, this can be done and I’ll implement this in the next version. Currently the connection is made to the share using the ANONYMOUS USER token, not the ConfigMgr Network Access Account. If you think about it this is by design, OSD mapped to the Package containing the Asset Check script using the Network Access Account in readiness for its execution, but when it was executed we then made another connection but this time it wasn’t handled by the Task Sequence engine and established using the Network Access Account
  • The server hosting the Network Share has to have a local Policy applied to allow the share to be used by the ANONYMOUS LOGON token
  • Using ANONYMOUS LOGON exposes Asset Tag, device naming standard and actual machine names for all to see within the company network, you can hide the share ($) but it can be navigated into if found. Most production networks will not tolerate this.

Using a ConfigMgr Package

The advantages

  • The source location for the package acts as the master copy and is distributed to the Distribution Points in the Hierarchy
  • The OSD device does not need to contact the network before it can check the Repository

The Disadvantages

  • The Repository file will now exist in your Package Source folder structure, you’ll need to change some permissions to allow Asset Check Repository editors access and full control, thus adding a dependency on the security configuration of the Package Source folder
  • Changes made to the Repository are latent, the meantime between edits and execution depends on how long it takes to copy the new Package source to the Distribution Points
  • If Run from Distribution Point is selected for the Deployment Types deployment, you’ll need to select the Packages option to copy the content to a package share, no big deal really

For this guide we’ll be using a Network Share. To be more secure use a Package, or modify the VBScript to establish the connection to the Network Share using credentials.

Configure requirements, and Deploy the Asset Check components

We’ll setup UDA affinity for the site, go through the process of creating and deploying a new ConfigMgr Package containing the VBScript, create and permission the Repository share while handling the Local Policy requirement for ANONYMOUS, and then we’ll modify an OS build Task Sequence to invoke Asset Check.

Configure the PXE Distribution Point or Bootable Media to accept UDA assignment's

Pretty simple to do, for the PXE Distribution Point just open the Distribution Points properties, Select the PXE Tab


From the drop down menu for User device Affinity select Allow user device affinity with automatic approval.

Do this to all your Distribution Points.

For Bootable Media, start the Create Bootable Media Wizard


The wizard will provide you with the option to enable or disable UDA. Recreate your media and from now on always choose this option when creating media.

Create the Asset Check Package

Prepare the Asset Check Package Source Location

First let’s copy the Asset Check VBScript to a new folder in your Package Source location. This location will be the one you specify when you follow the instructions below to create the Package.


Our 7K VBScript file now has it’s own Package Source location.

Prepare the ConfigMgr Package


Enter the Name as Asset Check, Version as 1 and set the Package Source Location using UNC as in the above example

Select Next


Select Do not create a program

Select Next


Select Next


Select Close

Find the new Package and open it’s Properties


Select Enable binary differential replication

Select Data Access tab


Select Copy the content in this package to a package share on distribution points

Select Distribution Settings tab


Select Distribute the content for this package to preferred distribution points

Select Automatically download content when packages are assigned to distribution points

Select Allow this package to be transferred via multicast (WinPE only)

Select OK

Now Distribute this package to your Distribution Points

Select the Package and choose Distribute Content


Make sure you’ve added your Distribution Points and proceed to complete the wizard, and check the Distribution Status to confirm it has deployed to all Distribution Points successfully.

Create the Asset Check Repository Network Share


You now need to locate a server that can host the Asset Check Repository Network Share. This Network Share requires ANONYMOUS LOGON rights assigned, and the server told to allow ANONYMOUS LOGON with that Network Share only. You may have to deal with this within Active Directory Group Policy, and a special Group Policy object applied to server hosting the Network Share, or you can override it using a Local Policy override which is what we’ll do shortly.

Create the Asset Check Repository folder anywhere on your server, I chose the root of my VM’s only disk, resulting in C:\AssetCheck-Repository

Right click the new folder and get to the Properties


Click Advanced Sharing


Select Share this folder, replace the Share Name, I shorten it to AssetCheck

Select Permissions


Select Add, enter ANONYMOUS LOGON, press OK

Make sure Read is the only option selected

Select OK, OK and Close to complete


Navigate to the newly created folder

And finally, copy the AssetRepository.CSV file to this new folder.

Configure Local Policy for Network Share ANONYMOUS LOGON

We now need to configure Local Policy to allow the new Network Share to be accessed by the ANONYMOUS LOGON token

Open Local Group Policy Editor on the server hosting the Asset Check Repository Network Share (Start\RUN\GPEDIT.MSC)


Navigate to Computer Configuration \ Windows Settings \ Security Settings \ Local Policies \ Security Options

Locate and double click Network access: Shares that can be accessed anonymously

Enter the name of the Network Share, in our case it is called AssetCheck

Select OK and close the editor to complete

The Asset Check Repository Network Share and the Repository file are now ready to be accessed by your devices during build time.

You can test this by booting up in WINPE and trying to connect to this share without providing any credentials.

Amend the Build Task Sequence to include Asset Check

Now you need to add the Run Command Line step to your Task Sequence to invoke Asset Check. You can locate this step anywhere from the beginning of the Task Sequence all the way up to the Apply Operating System, step at which point the script must of executed or it’ll be too late.

Open your Task Sequence, add a Run Command Line step


Call the new step Asset Check

Enter the command line as cscript.exe AssetCheck.vbs

Tick Package and Select Browse


Select the Asset Check Package (Asset Check 1) and Select OK

The run this step as the following account is not an option as it cannot be used at this stage in the WINPE boot sequence

Select the Options tab


For Success codes enter: 0 9997 9998 9999

Tick Continue on error

Close your Task Sequence to commit the changes

That’s it, the Asset Check mechanism has been integrated.

Let’s fire up a VM and see it working. Make the VM boot from a PXE Point or from Bootable Media.

As soon as WINPE has finished loading press F8 (assuming you have debug switched on in your Boot Images)

Enter the following WMIC command to retrieve the existing Asset Tag



The SMBIOSAssetTag property is returned, if it’s blank, you’ll need to set it using a tool that’ll do the job on that device. The device will need a reboot after it is set

Now that you have the Asset Tag for this device, open the Repository and add it as new entry using the correct notation, providing the device with a device name and if you want to test UDA add a domain user in DOMAIN\USER notation. Save and close the Repository file.

If the Repository is in a Package, you’ll need to Update the Distribution Points before proceeding

Now let your device begin the Build Task Sequence

Wait until the Asset Check step has been processed

Now we can check out what happened without having to wait for the Task Sequence to complete. You can do this either by viewing the SMSTSLOG, or running a Report, we will run a report


As you can see, it is pretty clear what Asset Check did (click on the image above for larger view), it’s output is structured so you can determine what was configured, quickly. Here it shows that the three key Task Sequence Variables where set with valid values


Once the machine has completed the build, it’ll appear in the console as a Client


Oddly the Devices resource record UDA property Machine Assigned to User is set to False, I’m sure I saw this report another value before but things are still working evidenced by the shots below


If you specified a UDA relationship in the Repository for this Device and it was successfully created, the Device will have a Primary User associated with it


And to make sure UDA was working Client-side, I setup the following deployment on the Site server


The 7Zip application (MSI) with a Deployment Type to Users Primary Devices


The 7Zip Deployment


There it is installed, before a domain user has even logged on

That’s pretty much it, I’ll work on a second version to smarten it up a bit more … if anything this shows how you can lasso together a few product elements to produce a very useful mechanism …


ConfigMgr 2012 SP1 Beta Boot Image Optional Components by Rob Marshall

Retrieving Identifying Information by Using the SMBIOS

Configuration Manager 2012: User Device Affinity and OS Deployment by John Vintzel

  • Small typo:

    Navigate to Computer Configuration \ Windows Settings \ Security Settings \ Security Options

    Should be:

    Navigate to Computer Configuration \ Windows Settings \ Security Settings \ Local Policies \ Security Options

  • Small typo:

    Navigate to Computer Configuration \ Windows Settings \ Security Settings \ Security Options

    Should be:

    Navigate to Computer Configuration \ Windows Settings \ Security Settings \ Local Policies \ Security Options

No Data