简体   繁体   中英

How can I get a list of Organizational Units from Active Directory?

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();

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;
}

Have you looked at the DirectorySearcher method?

Here are some examples at MSDN and bytes.com .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM