DomainControllers

Returns a list of domain controllers, sorted by site link cost. When used in the order provided, this will ensure that calls are made to the domain controllers with the least network latency and/or most bandwidth (as defined by the AD administrators, in AD Sites and Services)
Language:
C#
Keywords:
Active Directory
Code Snippet

using System.DirectoryServices;

using System.DirectoryServices.AccountManagement;

using System.DirectoryServices.ActiveDirectory;

 

/// <summary>

/// returns a list of domain controllers in the current domain, sorted by AD site link priority

/// </summary>

public static IEnumerable<string> DomainControllers()

{

    var adForest = Domain.GetComputerDomain().Forest;

    var adSite = ActiveDirectorySite.GetComputerSite();

 

    // Load all AD Inter-Site paths

    var Paths = ActiveDirectoryInterSiteTransport.FindByTransportType(

                                                     new DirectoryContext(DirectoryContextType.Forest, adForest.Name),

                                                     ActiveDirectoryTransportType.Rpc)

                                                 .SiteLinks

                                                 .OfType<ActiveDirectorySiteLink>()

                                                 .ToList()

                                                 .SelectMany(link =>

                                                     // create a cross join of all sites

                                                     from src in link.Sites.OfType<ActiveDirectorySite>()

                                                     from dest in link.Sites.OfType<ActiveDirectorySite>()

                                                     select new DijkstraRouteEngine.Path<string>()

                                                     {

                                                         Cost = link.Cost,

                                                         Source = src.Name,

                                                         Destination = dest.Name

                                                     })

                                                 .Where(p => p.Source != p.Destination);

 

    // calculate the shortest path to any other site

    var ShortestPaths = DijkstraRouteEngine.Engine.CalculateShortestFrom(adSite.Name, Paths)

                                                  .OrderBy(CompletePath => CompletePath.Value.Sum(PathStep => PathStep.Cost));

 

    // list of sites, ordered by cost from the current site (using best path possible)

    //  include the current site at the beginning, since it has 0 cost

    var ADSites = (new string[] { adSite.Name }).Union(ShortestPaths.SelectMany(s => s.Value.Select(x => x.Destination))
                                                                    .Distinct());

 

    // list of domain controllers in each site

    // note... use adForest.DomainControllers instead of adForest.Sites.Servers
    //         Servers may crash due to DNS lookup issues.

    // since a DC *MUST* have a site, this is a more reliable.

    return ADSites.SelectMany(s => adForest.Domains

                                           .OfType<Domain>()

                                           .SelectMany(d => d.DomainControllers

                                                             .OfType<DomainController>()

                                                             .Where(dc => dc.SiteName == s))

                                                             .Select(dc => dc.Name));

}

Example



Created 2012-03-07
comments powered by Disqus
Login