Get closest Domain Controller in current AD site without hard coding information

halfbit picture halfbit · Jun 12, 2012 · Viewed 9.5k times · Source

For instances when Active Directory takes too long to replicate data between sites, I need to ensure that the local AD replica contains the most up to date information.

  • How can I get a list of DomainControllers for the current site?

I haven't found anything on Codeproject or on StackOverflow

Answer

Peter picture Peter · Jul 13, 2012

Going to all this trouble is probably wasted effort. Unless you are experiencing issues with the built in logic for finding a domain controller you should just go with the built in method that returns one. According to Microsoft it automatically tries to find the closes one: http://technet.microsoft.com/en-us/library/cc978016.aspx.

Just use the static DomainController.FindOne method and pass in your directorycontext.

Update
Alright, try the code below, let me know how it works for you. It pings each, returns the roundtrip time, if -1 (no connection) it skips it. Flags PDC status if present. Orders by PDC status, followed by ping round trip.

    static void Main(string[] args)
    {
        var dcsInOrder = (from DomainController c in Domain.GetCurrentDomain().DomainControllers
                          let responseTime = Pinger(c.Name)
                          where responseTime >=0
                          let pdcStatus = c.Roles.Contains(ActiveDirectoryRole.PdcRole)
                          orderby pdcStatus, responseTime
                          select new {DC = c, ResponseTime = responseTime} 
                          ).ToList();

        foreach (var dc in dcsInOrder)
        {
            System.Console.WriteLine(dc.DC.Name + " - " + dc.ResponseTime);
        }

        System.Console.ReadLine();
    }

    private static int Pinger(string address)
    {
        Ping p = new Ping();
        try
        {
            PingReply reply = p.Send(address, 3000);
            if (reply.Status == IPStatus.Success) return (int)reply.RoundtripTime;
        }
        catch { }

        return -1;

    }