I've looked into the DirectoryServices class and it seems to be what I need, but I can't seem to find the classes/methods needed to fetch a collection of Organizational Units.
Can you guys give some suggestions?
I've looked into the DirectoryServices class and it seems to be what I need, but I can't seem to find the classes/methods needed to fetch a collection of Organizational Units.
Can you guys give some suggestions?
You need to use an appropriate DirectorySearcher
from System.DirectoryServices
, and you need to search for the organizationalUnit
AD class (I would recommend searching based on the objectCategory
which is single-valued 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);
}
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);
I know this thread is a little old, but I recently created a more efficient way of maneuvering through DirectoryEntries than the DirectorySearcher provides and wanted to share since this was the top result on Google. This example replicates the OU structure based on an initially specified starting point.
The DN path passed to the first constructor should 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 build, all you need to do is the following:
ADTree Root = null;
Task BuildOUStructure = Task.Factory.StartNew(() =>
{
ADTree = new ADTree("LDAP://ou=test,dc=lab,dc=net");
});
BuildOUStructure.Wait();
Have you looked at the DirectorySearcher method?
Here are some examples at MSDN and bytes.com.
This is my solution and it's working:
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's 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's 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;
}