Skip to content

Instantly share code, notes, and snippets.

@stdray
Created May 13, 2014 14:35
Show Gist options
  • Save stdray/ea54713d513684954734 to your computer and use it in GitHub Desktop.
Save stdray/ea54713d513684954734 to your computer and use it in GitHub Desktop.
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