Incremental Machine Naming In MDT

Posted by beakersoft | Posted in MDT | Posted on 11-03-2010


I have recently done some work with the Microsoft Deployment Toolkit, the successor to RIS and kind of extension to WDS. I used RIS quite extensively in the past, and while i did have it working quite well, it was a nightmare to actually setup (half the time it was easer to build 70 machines than to get RIS working!).  WDS and the MDT change all that.

It is now easy to build, and customise all parts of your OS deployment using these technology’s, but as I started using it there was one thing missing from it that old style RIS used to have.  Incremental naming of machines as you build them.

In RIS is was a simple matter of putting a variable into it’s settings, and it worked no problem, now however even though there are hundreds of new options naming in this manor is not one of them. I did a search around and come up with this article at Michael Niehause’s blog.

I have re-written the code from this posting in, i also had to make a couple of changes to my rules file to get it to work. The only differences between my code and Michael’s is mine is in and his is c# and mine does not add the machine account with a description to the active directory, I just let the install process do this for me.

The Code

Fire up a new web service project, and add this function to it:

WebMethod(Description:="Returns a new Computer Name to use." & _
" Inputs dns domain, a prefix and OU")> _
Public Function GetNewName(ByVal DnsDomain As String, _
ByVal NamePrefix As String) As String

'build the search, based on the passed domain, then the name prefix
Dim adRoot As New DirectoryEntry("LDAP://" & DnsDomain)
Dim dirSearch As New DirectorySearcher(adRoot, "(name=" & NamePrefix & "*)")
Dim existingNames As New Dictionary(Of String, Guid)()

'loop through the results
For Each result As SearchResult In dirSearch.FindAll()

'get the name, and create a guid holder
Dim strCurrName As String = result.Properties("name")(0).ToString.ToUpper
Dim netbootGuid As New Guid

'if we have a guid use that with this name
If result.Properties("netbootGuid").Count > 0 Then
netbootGuid = New Guid(DirectCast(result.Properties("netbootGuid")(0), Byte()))
End If

'add details to the dictonary, if they are not already there
If Not existingNames.ContainsKey(strCurrName) Then
existingNames.Add(strCurrName, netbootGuid)
End If


'now try and get the next name in sequence
Dim strNextName As String = Nothing

'loop through all the avalabe machine numbers up to max of 999
For i As Int32 = 1 To 999

Dim strNameTest As String = NamePrefix & i.ToString("000")

'is this name in the list, if not we have our name
If Not existingNames.ContainsKey(strNameTest) Then
strNextName = strNameTest
Exit For
End If

'return our new name
Return strNextName

End Function

What its doing

All the code is doing is querying your active directory for machines named like you specify, that end with a unique 3 char number (from 001 to 999). Once it finds one it returns the new name back to you. The good thing about this code is it will re-use any machine you have retired, so no numbers go to waste.

You pass the function the dns name of your active directory and the first part of the computer name (e.g. CA-HR-), and that’s it.

Calling the naming function from MDT

Once you have done your web service and it is callable from your web server, you need to alter your MDT rules file to call it and get a new name. This is all the sections you will have to fill in to get it to work, you will probaly have a lot more in your production system:

Properties=DnsDomain, NamePrefix


Parameters=DnsDomain, NamePrefix

All that is happening here is you are telling MDT to run an extra section called GetNewName, and that section is going to call your web service with 2 parameters (created in the default section) and then set OSDComputerName (the key that holds the machine name) to the returning string.


Odds are you wont get this right first time, but MDT writes does quite a good job of logging what it has done. On a machine your have deployed if you look in C:\MININT\SMSOSD\OSDLOGS you should be able to find the section that is trying to call the web service, and see what it did, and any errors if they occurred

Comments (7)

This looks like exactly what I need.

How do i get the code to work?

Ive copied the code into a notepad file and saved it with a .asmx extension but i get the following error when trying to run it

Server Error in ‘/MDT_Names’ Application.

Parser Error
Description: An error occurred during the parsing of a resource required to service this request. Please review the following specific parse error details and modify your source file appropriately.

Parser Error Message: The page must have a directive.

Source Error:

Line 1: _
Line 3: Public Function GetNewName(ByVal DnsDomain As String, _

Source File: /mdt_names/WDSNameExtras.asmx Line: 1

Version Information: Microsoft .NET Framework Version:2.0.50727.3615; ASP.NET Version:2.0.50727.3614

By the way, i think my IIS is setup correct becuase i have managed to get this working

I have gone through your post and i really enjoyed it reading. Thanks for sharing it with us.


I have compilation error on IIS 7

<WebMethod(Description:="Returns a new Computer Name to use." & _

BC30001: statement is not valid in a namespace.

i dont find answer

@vinc – It sounds like you might have removed the information about the namespace etc when you have created your asmx files. By default Visual studio will create some default info in the file, dont remove what it puts in, just add the code to the file

I have tried to get RIS naming working in MDT deployments for a while no success. I have not worked with web services before. Is there a way you can post how to create a web service and what else needs to be configured to get this working?

@Mike – creating a web service is a full article in its self, google is your friend. Its not hard all you really need is an iis server

Write a comment

Comments links could be nofollow free.