使用PrincipalSearcher进行单级搜索

时间:2013-07-11 18:03:53

标签: c# visual-studio-2012 active-directory ldap

我刚刚开始学习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;
    }

感谢您的建议!

2 个答案:

答案 0 :(得分: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;
    }

答案 1 :(得分: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];
    }
}