1

由于工作需要,我最近才开始学习 C#,我正在尝试编写一个方法来查询 Active Directory 中的特定 OU,并且只有那个 OU,没有子 OU。这是该方法的外观:

public List<string> getAllActiveUsers()
{
    PrincipalContext oPrincipalContext = GetPrincipalContext();
    UserPrincipal oUserPrincipal = new UserPrincipal(oPrincipalContext) 
    { 
        Enabled = true 
    };
    PrincipalSearcher oPrincipalSearcher = new PrincipalSearcher(oUserPrincipal);

    List<string> allUsers = new List<string>();

    foreach (var found in oPrincipalSearcher.FindAll())
    {
        allUsers.Add(found.DisplayName.ToString());
    }
    allUsers.Sort();
    return allUsers;
}

现在的方法只会拉取用户启用的用户帐户,但问题是它会拉取 subOU 中的帐户,这是不可取的。我已经用谷歌搜索了很长一段时间,没有真正回答这个问题,我充其量只是一个新手,如果有更改代码的建议,请告诉我最终方法会是什么样子。

任何和所有的帮助表示赞赏。

谢谢!

更新:显然我没有足够的谷歌搜索,所以我又试了一下,我发现使用 GetUnderlyingSearcher() 会起作用的建议,但我仍然不知道如何使用它。一些额外的研究产生了我需要的东西,这是更新的方法:

public List<string> getAllActiveUsers()
    {
        PrincipalContext oPrincipalContext = GetPrincipalContext();
        UserPrincipal oUserPrincipal = new UserPrincipal(oPrincipalContext) { Enabled = true };
        PrincipalSearcher oPrincipalSearcher = new PrincipalSearcher(oUserPrincipal);
        //Setting the search scope by going down to DirectorySearcher itself, as it's not possible to set this
        //via PrincipalSearcher directly
        ((DirectorySearcher)oPrincipalSearcher.GetUnderlyingSearcher()).SearchScope = SearchScope.OneLevel;

        List<string> allUsers = new List<string>();

        foreach (var found in oPrincipalSearcher.FindAll())
        {
            allUsers.Add(found.DisplayName.ToString());
        }
        allUsers.Sort();
        return allUsers;
    }

感谢您的建议!

4

2 回答 2

1

这段代码解决了我的问题:

((DirectorySearcher)oPrincipalSearcher.GetUnderlyingSearcher()).SearchScope = SearchScope.OneLevel;

最终方法如下所示:

public List<string> getAllActiveUsers()
    {
        PrincipalContext oPrincipalContext = GetPrincipalContext();
        UserPrincipal oUserPrincipal = new UserPrincipal(oPrincipalContext) { Enabled = true };
        PrincipalSearcher oPrincipalSearcher = new PrincipalSearcher(oUserPrincipal);
        //Setting the search scope by going down to DirectorySearcher itself, as it's not possible to set this
        //via PrincipalSearcher directly
        ((DirectorySearcher)oPrincipalSearcher.GetUnderlyingSearcher()).SearchScope = SearchScope.OneLevel;

        List<string> allUsers = new List<string>();

        foreach (var found in oPrincipalSearcher.FindAll())
        {
            allUsers.Add(found.DisplayName.ToString());
        }
        allUsers.Sort();
        return allUsers;
    }
于 2013-07-12T18:33:15.887 回答
0

嗯,我不熟悉PrincipalSearcher,但您可以尝试使用DirectorySearcher。它有一个选项SearchScope允许您设置OneLevelSubTree(或Base)。这是您可以尝试的一些示例代码(这是从我的生产代码中删除的,因此未经测试,甚至可能无法编译,但它应该给您一些想法):

DirectorySearcher dsr = new DirectorySearcher();
dsr.SearchRoot = new DirectoryEntry(settings.Path, settings.Username, settings.Password, settings.AuthType);
dsr.PageSize = 100;
dsr.SizeLimit = 0;
dsr.SearchScope = SearchScope.OneLevel;
dsr.Filter = "(&(objectclass=user)(sn=UserLastName))";
dsr.PropertiesToLoad.AddRange(new string[] { "sn", "givenName" });
using (SearchResultCollection src = dsr.FindAll())
{
    foreach (SearchResult sr in src)
    {
        string propName = lp.Name;
        ResultPropertyValueCollection rpvc = sr.Properties[propName];
        string val = (string)rpvc[0];
    }
}
于 2013-07-11T18:22:09.743 回答