How can I get a list of organizational units from Active Directory?

I looked at the DirectoryServices class and it seems to me that I need, but I can not find the classes / methods needed to collect a collection of organizational units.

Can you guys give any suggestions?

+11
source share
6 answers

You need to use the appropriate DirectorySearcher from System.DirectoryServices , and you need to find the organizationalUnit AD class (I would recommend searching based on objectCategory , which is unique and indexed - much faster than using objectClass ) - something like this:

 List<string> orgUnits = new List<string>(); DirectoryEntry startingPoint = new DirectoryEntry("LDAP://DC=YourCompany,DC=com"); DirectorySearcher searcher = new DirectorySearcher(startingPoint); searcher.Filter = "(objectCategory=organizationalUnit)"; foreach (SearchResult res in searcher.FindAll()) { orgUnits.Add(res.Path); } 
+19
source
 List<PlayerBO> source = new List<PlayerBO>(); DirectoryEntry root = new DirectoryEntry("LDAP://app.shgbit.com"); DirectoryEntry gbvision = root.Children.Find("OU=UMP"); DirectorySearcher searcher = new DirectorySearcher(gbvision); searcher.Filter = "(objectClass=computer)"; int index = 1; foreach (SearchResult each in searcher.FindAll()) { var box = each.GetDirectoryEntry(); source.Add(new PlayerBO { Id = index++, Name = box.Properties["name"].Value.ToString(), Description = box.Properties["description"].Value.ToString() }); } ListViewAD.ItemsSource = new SelectableSource<PlayerBO>(source); 
+4
source

I know this thread is a bit old, but I recently created a more efficient way to maneuver through DirectoryEntries than DirectorySearcher provides and would like to share, as this was the best result on Google. In this example, the OU structure is replicated based on the initial given starting point.

The DN path passed to the first constructor must be in the format "LDAP: // OU = StartingOU, DC = test, DC = com"

 using System.DirectoryServices; using System.Threading.Tasks; public class ADTree { DirectoryEntry rootOU = null; string rootDN = string.Empty; List<ADTree> childOUs = new List<ADTree>(); public DirectoryEntry RootOU { get { return rootOU; } set { rootOU = value; } } public string RootDN { get { return rootDN; } set { rootDN = value; } } public List<ADTree> ChildOUs { get { return childOUs; } set { childOUs = value; } } public ADTree(string dn) { RootOU = new DirectoryEntry(dn); RootDN = dn; BuildADTree().Wait(); } public ADTree(DirectoryEntry root) { RootOU = root; RootDN = root.Path; BuildADTree().Wait(); } private Task BuildADTree() { return Task.Factory.StartNew(() => { object locker = new object(); Parallel.ForEach(RootOU.Children.Cast<DirectoryEntry>().AsEnumerable(), child => { if (child.SchemaClassname.Equals("organizationalUnit")) { ADTree ChildTree = new ADTree(child); lock (locker) { ChildOUs.Add(ChildTree); } } }); }); } } 

To create everything you need to do the following:

 ADTree Root = null; Task BuildOUStructure = Task.Factory.StartNew(() => { ADTree = new ADTree("LDAP://ou=test,dc=lab,dc=net"); }); BuildOUStructure.Wait(); 
+3
source

The code provided by Jamie works great. To answer a MacGuyver question to use the Cast extension, you need to include a link to System.Linq in your code. I use this code to populate a TreeView showing OU in my AD environment:

 using System; using System.Data; using System.Linq; using System.Windows.Forms; using System.Threading.Tasks; using System.DirectoryServices; using System.Collections.Generic; using System.DirectoryServices.ActiveDirectory; namespace WindowsFormsApp8 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { treeView1.Nodes.Clear(); string top = string.Format("LDAP://DC={0}", Domain.GetCurrentDomain().Name.Replace(".", ",DC=")); ADTree tree = null; Task BuildOUStructure = Task.Factory.StartNew(() => { tree = new ADTree(top); }); BuildOUStructure.Wait(); foreach(ADTree t in tree.ChildOUs) { TreeNode node = new TreeNode(t.RootOU.Path); treeView1.Nodes.Add(node); if(t.ChildOUs.Count > 0) { AddChildren(node, t); } } } private void AddChildren(TreeNode parent, ADTree tree) { foreach(ADTree t in tree.ChildOUs) { TreeNode node = new TreeNode(t.RootOU.Path); parent.Nodes.Add(node); if(t.ChildOUs.Count > 0) { AddChildren(node, t); } } } } public class ADTree { DirectoryEntry rootOU = null; string rootDN = string.Empty; List<ADTree> childOUs = new List<ADTree>(); public DirectoryEntry RootOU { get { return rootOU; } set { rootOU = value; } } public string RootDN { get { return rootDN; } set { rootDN = value; } } public List<ADTree> ChildOUs { get { return childOUs; } set { childOUs = value; } } public ADTree(string dn) { RootOU = new DirectoryEntry(dn); RootDN = dn; BuildADTree().Wait(); } public ADTree(DirectoryEntry root) { RootOU = root; RootDN = root.Path; BuildADTree().Wait(); } private Task BuildADTree() { return Task.Factory.StartNew(() => { object locker = new object(); Parallel.ForEach(RootOU.Children.Cast<DirectoryEntry>().AsEnumerable(), child => { if (child.SchemaClassName.Equals("organizationalUnit")) { ADTree ChildTree = new ADTree(child); lock (locker) { ChildOUs.Add(ChildTree); } } }); }); } } } 

This is a simple Windows Forms application with TreeView (treeview1) and Button (button1) - hope this helps!

+2
source

Have you looked at the DirectorySearcher method?

Here are some examples on MSDN and bytes.com .

0
source

This is my solution and it works:

 List<string> DisplayedOU = new List<string>(); int step = 0; string span = "<span style='margin-left:6px;'> -- </span>"; private void getOU2() { string strRet = ""; DirectoryEntry domainRoot = new DirectoryEntry("LDAP://uch.ac/OU=ALL,DC=uch,DC=ac", "user", "pass"); // set up directory searcher based on default naming context entry DirectorySearcher ouSearcher = new DirectorySearcher(domainRoot); // SearchScope: OneLevel = only immediate subordinates (top-level OUs); // subtree = all OU in the whole domain (can take **LONG** time!) ouSearcher.SearchScope = SearchScope.Subtree; // ouSearcher.SearchScope = SearchScope.Subtree; // define properties to load - here I just get the "OU" attribute, the name of the OU ouSearcher.PropertiesToLoad.Add("ou"); // define filter - only select organizational units ouSearcher.Filter = "(objectCategory=organizationalUnit)"; int cnt = 0; foreach (SearchResult deResult in ouSearcher.FindAll()) { string temp = deResult.Properties["ou"][0].ToString(); strRet += FindSubOU(deResult.Properties["adspath"][0].ToString(), cnt); } Literal1.Text = strRet; } private string FindSubOU(string OU_Path, int cnt) { string strRet = ""; DirectoryEntry domainRoot = new DirectoryEntry(OU_Path, "user", "pass"); // set up directory searcher based on default naming context entry DirectorySearcher ouSearcher = new DirectorySearcher(domainRoot); // SearchScope: OneLevel = only immediate subordinates (top-level OUs); // subtree = all OU in the whole domain (can take **LONG** time!) ouSearcher.SearchScope = SearchScope.Subtree; // ouSearcher.SearchScope = SearchScope.Subtree; // define properties to load - here I just get the "OU" attribute, the name of the OU ouSearcher.PropertiesToLoad.Add("ou"); // define filter - only select organizational units ouSearcher.Filter = "(objectCategory=organizationalUnit)"; //adspath // do search and iterate over results foreach (SearchResult deResult in ouSearcher.FindAll()) { string temp = deResult.Properties["ou"][0].ToString(); if (!DisplayedOU.Contains(deResult.Properties["ou"][0].ToString())) { string strPerfix = ""; for (int i = 0; i < step; i++) strPerfix += span; strRet += strPerfix + ++cnt + ". " + deResult.Properties["ou"][0].ToString() + " ----> " + deResult.Properties["adspath"][0].ToString() + "<br />"; DisplayedOU.Add(deResult.Properties["ou"][0].ToString()); step++; strRet += FindSubOU(deResult.Properties["adspath"][0].ToString(), cnt); step--; } } return strRet; } 
0
source

All Articles