检查是否启用了UserPrincipal

时间:2014-08-11 14:40:35

标签: c# active-directory

我使用C#代码查询Active Directory。我遇到的主要问题是确定帐户是否已被禁用。通过阅读许多在线文章,似乎不能单独依赖属性UserPrincipal.Enabled来确定是否启用了用户帐户。很公平,因为它是一个可以为空的布尔值,但是当AD管理员禁用某个帐户时,这似乎设置为false。我遇到的问题是当我查询客户端的AD时,我发现大多数用户帐户UserPrincipal对象都为此属性返回false。因此,当我使用此代码检查帐户是否被禁用时:

private bool IsUserEnabled(UserPrincipal userPrincipal)
{
        bool isEnabled = true;

        if (userPrincipal.AccountExpirationDate != null)
        {
            // Check the expiration date is not passed.
            if (userPrincipal.AccountExpirationDate <= DateTime.Now)
            {
                Log.DebugFormat("User {0} account has expired on {1}", userPrincipal.DisplayName, userPrincipal.AccountExpirationDate.Value);
                isEnabled = false;
            }
        }

        if (userPrincipal.IsAccountLockedOut())
        {
            isEnabled = false;
            Log.DebugFormat("User {0} account is locked out", userPrincipal.DisplayName);
        }

        if (userPrincipal.Enabled != null)
        {
            isEnabled = userPrincipal.Enabled.Value;
            Log.DebugFormat("User {0} account is Enabled is set to {1}", userPrincipal.DisplayName, userPrincipal.Enabled.Value);
        }

        return isEnabled;
}

由于userPrincipal.Enabled检查,大多数帐户似乎已停用。

但是,如果我将其删除并仅依靠帐户到期日期和帐户锁定属性,那么我可能会错过使用Active Directory中的复选框禁用该帐户的人员,而无需设置帐户到期日期

启用的所有帐户返回false实际上是可以登录域的活动帐户。

如何检查帐户是否实际启用?

3 个答案:

答案 0 :(得分:1)

我遇到了类似的问题,同样感到困惑!

我最初使用System.DirectoryServices.DirectorySearcher搜索已停用的用户。 AD用户记录的状态(re:禁用,锁定,密码到期等)存储在UserAccountControl属性中。您可以将过滤器传递给DirectorySearcher,通过将UserAccountControl属性指定为过滤器的一部分来定位禁用帐户。

我从不喜欢这种方法,因为它等于使用魔术字符串和一些魔法数字来构建查询;例如,这是用于查找已禁用帐户的过滤器:

 var searcher = new DirectorySearcher(dirEntry)
            {
                Filter = "(UserAccountControl:1.2.840.113556.1.4.803:=2)",
                PageSize = 50
            };

当我切换到使用UserPrincipal时,我很高兴看到这个非常方便&#34;启用&#34;在类上的财产权。至少在我意识到它没有返回DirectorySearcher过滤器返回的相同值之前。

不幸的是,我可以找到确定帐户是否实际启用的唯一可靠方法是深入挖掘底层的DirectoryEntry对象,然后直接检查UserAccountControl属性,即:

var result = (DirectoryEntry)userPrincipal.GetUnderlyingObject();
var uac = (int)result.Properties("useraccountcontrol");
var isEnabled = !Convert.ToBoolean(uac & 2);

注意 - UserAccountControl属性是&#34;标记&#34;枚举;可以在此处找到UserAccountControl属性的所有可能值:https://msdn.microsoft.com/en-us/library/aa772300(v=vs.85).aspx

我最终将上面的代码段构建成一个小扩展方法;幸运的是,这项额外的工作来检索UserAccountControl属性并没有明显减缓我的AD查询。

答案 1 :(得分:0)

我可以告诉你在我的一个应用程序中对我有用的东西。以下是我的应用程序的片段:

using (PrincipalContext pc = new PrincipalContext(ContextType.Domain, "domain.com"))
{
    using (UserPrincipal user = UserPrincipal.FindByIdentity(pc, "Doe, John"))
    {
        Console.Out.Write(user.Enabled);
    }
}

对我来说,这准确地返回帐户是否已启用。

答案 2 :(得分:0)

我得到了一个解决方案,方法是扩展结果并转到基础并扩展基础。您将在此处看到 enabled 属性。然后,我右键单击表达式并添加以监视并将监视表达式复制到我的代码中。

  using (var context = new PrincipalContext(ContextType.Domain, "xyz.com", "Administrator", "xyz123"))
        {
            using (var searcher = new PrincipalSearcher(new UserPrincipal(context)))
            {
             foreach (var result in searcher.FindAll())
                {
                  DirectoryEntry de = result.GetUnderlyingObject() as DrectoryEntry;
             foreach (String key in de.Properties.PropertyNames)
                {
                   Console.WriteLine(key + " : " + de.Properties[key].Value);
                }
               Console.WriteLine("Enabled: "    +((System.DirectoryServices.AccountManagement.AuthenticablePrincipal)(result)).Enabled);
               Console.WriteLine("First Name: " + de.Properties["givenName"].Value);
                    }
                 }
             }
        Console.ReadLine();

((System.DirectoryServices.AccountManagement.AuthenticablePrincipal)(result)).Enabled 可以很好地使用户列表中的 enabled 正确或错误。