C#操纵ActiveDirectory用户的问题

时间:2016-08-15 15:55:35

标签: c# active-directory

我正在为我们的组织编写某种迷你AD工具(使用VS-C#)并遇到问题。

我有一个搜索用户的主要功能(当我在列表视图中点击它时)和一些操纵用户对象的功能。

public DirectoryEntry GetUser(string username)
    {
        try
        {
            Forest currentForest = Forest.GetCurrentForest();
            GlobalCatalog gc = currentForest.FindGlobalCatalog();

            using (DirectorySearcher searcher = gc.GetDirectorySearcher())
            {
                searcher.Filter = "(&((&(objectCategory=Person)(objectClass=User)))(samaccountname=" + username + "*))";
                SearchResult results = searcher.FindOne();
                if (!(results == null))
                {

                    DirectoryEntry de = new DirectoryEntry(results.Path, strAdminUser, strAdminPass, AuthenticationTypes.Secure);
                    de.RefreshCache(new string[] { "canonicalName" });
                    de.Path = de.Properties["canonicalName"].Value.ToString();
                    de.CommitChanges();
                    return de;
                }
                else
                {
                    return null;
                }
            }
        }
        catch (DirectoryServicesCOMException e)
        {
            System.Windows.Forms.MessageBox.Show(e.Message);
            return null;
        }
    }

这是一个检查用户是否被锁定的函数示例:

public bool IsUserLocked(string username)
    {
         try
         {
             DirectoryEntry de = GetUser(username);
             string attName = "msDS-User-Account-Control-Computed";
             de.RefreshCache(new string[] { attName });
             const int UF_LOCKOUT = 0x0010;
             int userFlags = /*(int)*/Convert.ToInt32(de.Properties[attName].Value);
             if ((userFlags & UF_LOCKOUT) == UF_LOCKOUT)
             {
                 return true;
             }
             de.Dispose();
             return false;
         }
         catch (DirectoryServicesCOMException e)
         {
            System.Windows.Forms.MessageBox.Show(e.Message);
            return false;
         }
      }

检查用户锁定状态的功能始终失败并显示错误:"未指定错误" ,但如果我没有更改目录条目&#39 ; s第一个函数中的路径"服务器不愿意处理请求" 错误(我使用正确的服务用户名和密码以及所需的所有权限)但它仍然会发生。

有人能发现问题吗?

2 个答案:

答案 0 :(得分:0)

如何使用System.DirectoryServices.AccountManagement命名空间?如果使用新命名空间没有问题,可以使用更简单的方法检查用户帐户是locked还是unlock

public bool IsUserLocked (string username)
{
   using(PrincipalContext ctx = new PrincipalContext(ContextType.Domain, "yourdomain.com")
    {
       using (UserPrincipal user = UserPrincipal.FindByIdentity(ctx, username)
       {
          if (user != null) return user.IsAccountLockedOut();
       }
    }
    return null;
}

同样,如果需要,您可以unlock用户帐户。

...

if (user != null)
{
   user.UnlockAccount();
   user.Save();
}

答案 1 :(得分:0)

得到了......

这解决了我的问题: de.Path = results.Path.Replace(“GC:// DCNAME。”,“LDAP://”); 由于我正在全球目录中搜索,我不得不替换路径中的一部分以使其与正确的路径匹配:

public DirectoryEntry GetUser(string username)
    {
        try
        {
            Forest currentForest = Forest.GetCurrentForest();
            GlobalCatalog gc = currentForest.FindGlobalCatalog();

            using (DirectorySearcher searcher = gc.GetDirectorySearcher())
            {
                searcher.Filter = "(&((&(objectCategory=Person)(objectClass=User)))(samaccountname=" + username + "*))";
                SearchResult results = searcher.FindOne();
                if (!(results == null))
                {

                    DirectoryEntry de = new DirectoryEntry(results.Path, strAdminUser, strAdminPass, AuthenticationTypes.Secure);
                    de = new DirectoryEntry(results.Path);
                    de.Path = results.Path.Replace("GC://DCNAME.", "LDAP://");
                    de.CommitChanges();
                    //System.Windows.Forms.MessageBox.Show(de.Path);
                    return de;
                }
                else
                {
                    return null;
                }
            }
        }
        catch (DirectoryServicesCOMException e)
        {
            System.Windows.Forms.MessageBox.Show(e.Message);
            return null;
        }
    }

现在路径以正确的格式返回名为 GetUser 的函数:)