RIS-style naming with MDT 2010: Use a web service

I’ve been toying around with using a web service that could be used to implement RIS-style computer naming.  Unfortunately, I haven’t had time to work on it much in the last year or so, so I’ll post the code as-is and tell you up front that it’s not really complete – you might need to make some changes to it to meet your specific needs.  So here’s the code (written using Visual Studio 2008 and .NET 3.5), which shows how easy it is to do LDAP queries and object creation using .NET:

using System;

using System.Collections;

using System.Collections.Generic;

using System.ComponentModel;

using System.Diagnostics;

using System.DirectoryServices;

using System.Data;

using System.Linq;

using System.Web;

using System.Web.Services;

using System.Web.Services.Protocols;

using System.Xml.Linq;

namespace DemoWebService


    [WebService(Namespace = "http://tempuri.org/")]

    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]


    public class NameService : System.Web.Services.WebService



        public String GenerateName(String dnsDomain, String prefix, String uuid, String machineObjectOU)


            // Build the search

            DirectoryEntry entry =

                new DirectoryEntry("LDAP://" + dnsDomain);

            DirectorySearcher search = new DirectorySearcher(entry,

               "(name=" + prefix + "*)");

            // Execute the search and build a list of the matching names and their UUIDs

            Dictionary<String, Guid> existingNames = new Dictionary<String, Guid>();

            foreach (SearchResult result in search.FindAll())


                String name = result.Properties["name"][0].ToString().ToUpper();

                Guid netbootGuid = new Guid();

                if (result.Properties["netbootGuid"].Count > 0)

                    netbootGuid = new Guid((byte[])result.Properties["netbootGuid"][0]);

                Trace.WriteLine("Found computer " + name + " with GUID " + netbootGuid.ToString());

                existingNames.Add(name, netbootGuid);


            // See if we can find an existing match.  If so, return it.

            Guid existingUuid = new Guid(uuid);

            if (existingNames.ContainsValue(existingUuid))


                foreach (String name in existingNames.Keys)

                    if (existingNames[name] == existingUuid)


                        // TODO: Maybe we want to move the computer object to the specified OU

                        return name;



            // Find the first available name in sequence

            String nextName = null;

            for (Int32 i = 1; i <= 999; i++)


                String testName = prefix + i.ToString("000");

                if (!existingNames.ContainsKey(testName))


                    nextName = testName;




            if (nextName == null)

                return null;  // All names were taken

            // Add the computer to AD



                DirectoryEntry dirEntry = new DirectoryEntry("LDAP://" + machineObjectOU);

                DirectoryEntry newUser = dirEntry.Children.Add("CN=" + nextName, "computer");

                newUser.Properties["samAccountName"].Value = nextName + "$";

                newUser.Properties["netbootGUID"].Value = existingUuid.ToByteArray();

                newUser.Properties["description"].Value = "Added by MDT";




            catch (Exception e)


                Trace.WriteLine("Unable to add computer: " + e.ToString());


            // Return the name

            return nextName;




To use this, you would add an entry to CustomSettings.ini to call the web service.  That would look something like this:

Priority=Default, GetName
Properties=DnsDomain, Prefix


Parameters=DnsDomain, Prefix, UUID, MachineObjectOU

The web service would be passed the DNS domain name (mydomain.com), computer prefix (MDTTEST), the current machine’s SMBIOS UUID, and the OU to which new computers should be added.  It will return a name starting with the specified prefix and ending with the next available three-digit number.  So the first machine would be MDTTEST001, the second MDTTEST002, etc.  These computer names are added to Active Directory with the “netbootGUID” attribute set, so that if the machine is ever rebuilt it will use the same computer name again.  (The code purposely doesn’t try to find any computer object with that SMBIOS UUID.  Instead, it only looks for computers with the right prefix that have a matching UUID.  This might not be the behavior you want, but it was the behavior I wanted.)

The output from ZTIGather.wsf when processing this INI file would look something like this:

Added new custom property DNSDOMAIN
Added new custom property PREFIX
Using from [Settings]: Rule Priority = DEFAULT, GETNAME
------ Processing the [DEFAULT] section ------
Property MACHINEOBJECTOU is now = OU=Workstations,DC=mydomain,DC=com
Using from [DEFAULT]: MACHINEOBJECTOU = OU=Workstations,DC=mydomain,DC=com
Property DNSDOMAIN is now = mydomain.com
Using from [DEFAULT]: DNSDOMAIN = mydomain.com
Property PREFIX is now = MDTTEST
------ Processing the [GETNAME] section ------
Determining the INI file to use.
Using COMMAND LINE ARG: Ini file = CS.ini
Finished determining the INI file to use.
Using COMMAND LINE ARG: Ini file = CS.ini
CHECKING the [GETNAME] section
About to execute web service call using method POST to http://server/NameService.asmx/GenerateName: DnsDomain=mydomain.com&Prefix=MDTTEST&UUID=814100CD-CE48-CB11-A536-B7561D1E4450&MachineObjectOU=OU=Workstations,DC=mydomain,DC=com
Response from web service: 200 OK
Successfully executed the web service.
Obtained OSDCOMPUTERNAME value from web service:  string = MDTTEST001

This isn’t quite as flexible as the RIS naming, where you could use other variables in the computer name, but there’s no reason you couldn’t add more logic to cover those cases too.  There’s also no guarantee that the web service will add the computer account to the same DC that the computer ends up using, which could cause some naming conflicts if the new computer object doesn’t replicate before the computer tries to join the domain.  Use at your own risk 🙂

Comments (7)
  1. Anonymous says:

    Hey ,

    Correct me if im wrong but this solution will not work with Windows 7 and autoname deploymebt ? I have tested it and 7 just doestn like object already existing in domain. It claims that it cannot reuse the computer account

  2. Anonymous says:

    This seems more correct?:

    if (result.Properties["netbootGuid"].Count > 0){

     netbootGuid = new Guid((byte[])result.Properties["netbootGuid"][0]);

     Trace.WriteLine("Found computer " + name + " with GUID " + netbootGuid.ToString());

     existingNames.Add(name, netbootGuid);


  3. Anonymous says:

    Hi Michael – thanks for the code, this web service will be really useful for us.  We have the service returning a machine name to MDT, as can be seen in our BDD.log file.  The web service is creating the corresponding account successfully in AD.  However, the domain join is failing.  If I attempt a manual domain join after MDT is finished, I get an error saying the account already exists.  Is there a particular attribute that needs to be set to make it a "managed" account that's missing from your code perhaps? Or is this a security issue?

  4. Alslinet says:

    How do i acctually implement this. I have problems with values not beeing set. All values remain blank except the UUID.

  5. LTennent says:

    I work with RayDiack and we’ve finally got this working with an amendment to Michael’s initial code.

    The account that was created by the webservice was created as disabled and didn’t allow the domain join. By adding the following line to change the attributes of the computer account: newUser.Properties["userAccountControl"].Value = 4128; the problem was

    See the following article for other userAccountControl options:


    The other issue we ran into was running the web service as an account with permission to join computers to the domain.

    For this we set up an application pool and set the identity to an account with permissions. Add this account to the group "IIS_WPG" and then give the account permissions to C:winnttemp folder. You can copy the permission of the network service account.

    If you encounter this error "Request format is unrecognized for URL unexpectedly ending in ‘/???’" check out this URL:

    http://www.rikware.com/…/URL-Unexpectedly-Ending-Error-with-ASPNET-20-Web-Services.aspx and make the relevent changes to the webconfig file.

    Thanks again for sharing the web service. We finally have fully automated builds again with no pre-staging!!!

  6. Rick Jongbloed says:


    there is a bug in this code.

    The part existingNames.Add(name, netbootGuid); need to be in the loop instead of under the trace.

  7. Serterkek says:

    Hi, Rick

    Sorry I am very new to subject, can you please put some step by step instructions.


Comments are closed.

Skip to main content