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 vb.net, 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 vb.net 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.
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()))
'add details to the dictonary, if they are not already there
If Not existingNames.ContainsKey(strCurrName) Then
'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
'return our new name
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:
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