Created
May 13, 2014 14:35
-
-
Save stdray/ea54713d513684954734 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.CodeDom.Compiler; | |
using System.Collections; | |
using System.Collections.Generic; | |
using System.Diagnostics; | |
using System.DirectoryServices; | |
using System.DirectoryServices.ActiveDirectory; | |
using System.IO; | |
using System.Linq; | |
using System.Threading.Tasks; | |
namespace DomainTree | |
{ | |
internal class Program | |
{ | |
private static void Main() | |
{ | |
var domains = Forest.GetCurrentForest().Domains; | |
var timer = Stopwatch.StartNew(); | |
var tree2 = GetDomainTree(domains); | |
var successivelyTime = timer.ElapsedMilliseconds; | |
timer.Restart(); | |
var tree = GetDomainTreeParallel(domains).Result; | |
var parallelTime = timer.ElapsedMilliseconds; | |
Console.WriteLine(AsString(tree)); | |
Console.WriteLine(AsString(tree2)); | |
Console.WriteLine(timer.ElapsedMilliseconds); | |
Console.WriteLine("Get domain tree parallel: {0}ms", parallelTime); | |
Console.WriteLine("Get domain tree successively: {0}ms", successivelyTime); | |
Console.ReadLine(); | |
} | |
static string AsString(IEnumerable<DirectoryEntry> tree) | |
{ | |
var writer = new IndentedTextWriter(new StringWriter()); | |
foreach (var entry in tree) | |
foreach (var node in EnumerateEntry(entry)) | |
{ | |
writer.Indent = node.Item1; | |
writer.WriteLine(node.Item2.Name); | |
} | |
return writer.InnerWriter.ToString(); | |
} | |
static IEnumerable<Tuple<int, DirectoryEntry>> EnumerateEntry(DirectoryEntry entry, int level = 0) | |
{ | |
yield return Tuple.Create(level, entry); | |
var children = entry | |
.Children | |
.OfType<DirectoryEntry>() | |
.Where(e => e != null) | |
.SelectMany(e => EnumerateEntry(e, level + 1)); | |
foreach (var child in children) | |
yield return child; | |
} | |
static Task<DirectoryEntry> GetDirectoryEntry(ActiveDirectoryPartition domain) | |
{ | |
return Task.Factory.StartNew(() => | |
{ | |
try | |
{ | |
return domain.GetDirectoryEntry(); | |
} | |
catch | |
{ | |
return null; | |
} | |
}); | |
} | |
static async Task<IEnumerable<DirectoryEntry>> GetDomainTreeParallel(IEnumerable domains) | |
{ | |
var tasks = domains | |
.OfType<Domain>() | |
.Select(GetDirectoryEntry); | |
return (await Task.WhenAll(tasks)) | |
.Where(e => e != null); | |
} | |
static IEnumerable<DirectoryEntry> GetDomainTree(IEnumerable domains) | |
{ | |
return domains | |
.OfType<Domain>() | |
.Select(d => d.GetDirectoryEntry()) | |
.ToList(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment