使用c#查找AD中的所有锁定用户

时间:2014-09-03 23:16:22

标签: c# active-directory

下面列出的代码对我来说很好但是我想要一个锁定而不是指定特定用户的所有用户的列表,可以帮助我拓宽这个代码的范围

using (var context = new PrincipalContext( ContextType.Domain ))
{
     using (var user = UserPrincipal.FindByIdentity( context,
                                                     IdentityType.SamAccountName,
                                                     name ))
     {
          if (user.IsAccountLockedOut())
          {
              ... your code here...
          }
     }
}

上面列出的代码对我来说很好,但我希望锁定所有用户的列表,而不是指定特定用户。

这是最终工作的结果 - 感谢所有贡献者 当用户被锁定时,他们不会去"没有锁定"直到他们登录(当在ldap搜索中引用lockedout子句时);所以...使用锁定的qry为您提供一个广泛的锁定用户列表,然后您可以使用isaccountlockedout()方法缩小范围。此致!

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.DirectoryServices;
using System.DirectoryServices.ActiveDirectory;
using System.DirectoryServices.AccountManagement;

namespace ConsoleApplication5
{
    class Lockout : IDisposable
    {
        DirectoryContext context;
        DirectoryEntry root;


        public Lockout()
        {
            string domainName = "domain.com";
            this.context = new DirectoryContext(
              DirectoryContextType.Domain,
              domainName
              );

            //get our current domain policy
            Domain domain = Domain.GetDomain(this.context);

            this.root = domain.GetDirectoryEntry();

        }

        public void FindLockedAccounts()
        {

            string qry = " (&(&(&(objectCategory=person)(objectClass=user)(lockoutTime:1.2.840.113556.1.4.804:=4294967295)(!UserAccountControl:1.2.840.113556.1.4.803:=2)(!userAccountControl:1.2.840.113556.1.4.803:=65536)))) ";
            DirectorySearcher ds = new DirectorySearcher(
              this.root,
              qry
              );

            using (SearchResultCollection src = ds.FindAll())
            {
                foreach (SearchResult sr in src)
                {


                    using (var context = new PrincipalContext( ContextType.Domain ))
                        {
    string name = sr.Properties["SamAccountName"][0].ToString();
     using (var user = UserPrincipal.FindByIdentity( context,
                                                     IdentityType.SamAccountName,
                                                     name ))
                                 {  
          if (user.IsAccountLockedOut())
                                                 {
              Console.WriteLine("{0} is locked out", sr.Properties["name"][0]);

                                                 } 
                                 }
                        }



                }
            }
        }

        public void Dispose()
        {
            if (this.root != null)
            {
                this.root.Dispose();
            }
        }
    }


}

2 个答案:

答案 0 :(得分:2)

编辑:误读问题。更新的答案

立即尝试

为什么不呢:

        var lockedUsers = new List<UserPrincipal>();
        using (var context = new PrincipalContext(ContextType.Domain))
        {
            GroupPrincipal grp = GroupPrincipal.FindByIdentity(context, IdentityType.SamAccountName, "Domain Users");
            foreach (var userPrincipal in grp.GetMembers(false))
            {
                var user = UserPrincipal.FindByIdentity(context, IdentityType.SamAccountName, userPrincipal.UserPrincipalName);                        
                if (user != null)
                {
                    if (user.IsAccountLockedOut())
                    {
                        lockedUsers.Add(user);
                    }
                }
            }
        }
//Deal with list here

Check here if you'd like to see more

答案 1 :(得分:2)

您可以使用lockoutTime属性,但是,它不一定是微不足道的。该属性具有用户被锁定的时间。因此,如果您的域具有单个锁定策略,则可以搜索lockoutTime值大于或等于(UTC现在 - 锁定持续时间)的所有人。

如果您通过细粒度密码策略有多个锁定策略,那么这不是那么容易,因为您需要按用户计算它。

如果您的域名具有永久锁定功能(例如,您必须请求解锁帐户),则可以搜索大于零的内容。