【问题标题】:Get all users from Active Directory?从 Active Directory 获取所有用户?
【发布时间】:2012-06-12 09:53:44
【问题描述】:

我有以下代码:

        DirectoryEntry directoryEntry = default(DirectoryEntry);
        // Binding object. 
        DirectoryEntry objGroupEntry = default(DirectoryEntry);
        // Group Results. 
        DirectorySearcher objSearchADAM = default(DirectorySearcher);
        // Search object. 
        SearchResultCollection objSearchResults = default(SearchResultCollection);
        // Binding path. 
        ActiveDirectory result = new ActiveDirectory();
        ActiveDirectoryItem treeNode;

    string adServer = ADTestProject.Properties.Settings.Default.Server;
    string adDomain = ADTestProject.Properties.Settings.Default.Domain;
    string adUsername = ADTestProject.Properties.Settings.Default.AdiminUsername;
    string password = ADTestProject.Properties.Settings.Default.Password;

    string[] dc = adDomain.Split('.');

    string dcAdDomain = string.Empty;

    foreach (string item in dc)
    {
        if (dc[dc.Length - 1].Equals(item))
            dcAdDomain = dcAdDomain + "DC=" + item;
        else
            dcAdDomain = dcAdDomain + "DC=" + item + ",";
    }

    // Get the AD LDS object. 

        if (pathToAD.Length > 0)
            directoryEntry = new DirectoryEntry("LDAP://" + adServer + "/CN=Users," + dcAdDomain, adUsername, password);
        else
            directoryEntry = new DirectoryEntry();

        DirectorySearcher ds = new DirectorySearcher(directoryEntry);
        ds.SearchScope = SearchScope.Subtree;
        ds.Filter = "(&(objectClass=group))";

        objSearchResults = ds.FindAll();

然后这个:

if (objSearchResults.Count != 0)
{
    foreach (SearchResult objResult in objSearchResults)
    {
        objGroupEntry = objResult.GetDirectoryEntry();
        result.ActiveDirectoryTree.Add(new ActiveDirectoryItem() 
        { Id = objGroupEntry.Guid, 
            ParentId = objGroupEntry.Parent.Guid, 
            AccountName = objGroupEntry.Name, 
            Type = ActiveDirectoryType.Group, 
            PickableNode = false 
        });

        foreach (object child in objGroupEntry.Properties["member"])
        {
            treeNode = new ActiveDirectoryItem();
            var path = child.ToString().Replace;
            using (var memberEntry = new DirectoryEntry(path))
            {

                if (memberEntry.Username != null && memberEntry.SchemaEntry.Name.CompareTo("group") != 0 
                    && memberEntry.Properties.Contains("sAMAccountName") && memberEntry.Properties.Contains("objectSid"))
                {
                    treeNode.Id = Guid.NewGuid();
                    treeNode.ParentId = objGroupEntry.Guid;
                    treeNode.AccountName = memberEntry.Properties["sAMAccountName"][0].ToString();
                    treeNode.Type = ActiveDirectoryType.User;
                    treeNode.PickableNode = true;
                    treeNode.FullName = memberEntry.Properties["Name"][0].ToString();

                    byte[] sidBytes = (byte[])memberEntry.Properties["objectSid"][0];
                    treeNode.ObjectSid = new System.Security.Principal.SecurityIdentifier(sidBytes, 0).ToString();

                    result.ActiveDirectoryTree.Add(treeNode);
                }
            }
        }
    }
}

Child.ToString 可能如下所示:

CN=S-1-5-18,CN=ForeignSecurityPrincipals,DC=MyDomain,DC=local

问题是 memberEntry 的属性有很多异常?为什么?

例外是这样的:

'memberEntry.Name' 抛出类型异常 'System.Runtime.InteropServices.COMException' 字符串 {System.Runtime.InteropServices.COMException} - 未指定的错误 -2147467259

堆栈跟踪:在 System.DirectoryServices.DirectoryEntry.Bind(布尔 throwIfFail)
在 System.DirectoryServices.DirectoryEntry.Bind() 在 System.DirectoryServices.DirectoryEntry.get_Name()

【问题讨论】:

  • catch (Exception e) { throw e; } - 有点毫无意义,你失去了整个调用堆栈。改用throw; 或去掉整个try \ catch 块。
  • 是的,你是对的,还没有清理代码。谢谢
  • 由于你没有提到你得到的确切异常,我们只能在这里猜测,但也许 Name 属性没有在所有对象上定义?你无条件地得到它,这可能是问题所在。
  • 我已经更新了异常。我在所有 30 件商品上都得到了这个(例外)?
  • 那是 COM 错误 0x80004005:查找失败。因此,在其中任何一个上都找不到 Name 属性(或者您因为权限而无法读取它)-您是否尝试过使用 ADSI 检查该属性是否存在?

标签: .net active-directory


【解决方案1】:

在与 OP 交谈后,我们确定问题出在DirectoryEntry 中使用的path 变量中,并且需要在 OP 的环境中进行显式身份验证。

相关变化是:

using (var memberEntry = new DirectoryEntry(path))

到

using (var memberEntry = new DirectoryEntry("LDAP://" + adServer + "/" + path, adUsername, password))

详情:Full transcript

【讨论】:

    【解决方案2】:

    这可能与get a list of user from the AD 重复

    但是,尽管如此,有一篇文章描述了很多有用的 查询广告on CodeProject: Querying MS AD using dot Net

    【讨论】:

    • 我不认为两者相似。链接中的问题是询问如何吸引用户。这里的问题是查找失败,OP 必须找出原因。
    猜你喜欢
    • 1970-01-01
    • 2023-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多