2014-09-03 72 views
3

下面列出的代码适用于我,但我希望列出所有锁定的用户,而不是指定特定的用户,有人可以帮助我扩大此代码的范围请在AD中使用c查找所有锁定的用户#

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

上面列出的代码工作正常,我不过我想,而不是指定特定用户已锁定所有用户的列表。

这是什么结束了工作 - 感谢所有贡献者。
当用户被锁定时,他们在登录之前不会进入“未锁定状态”(当在ldap搜索中引用锁定子句时);所以...使用锁定的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

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

现在就来试试

为什么不干脆:

 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

+0

这仍然引用请求提供名称值的“名称” – ModS 2014-09-03 23:33:19

+1

我添加了一个编辑来解决这个问题。 – 2014-09-03 23:36:48

+0

谢谢!唯一的问题是“isaccountlockedout()”正在创建一个错误,“accountmanagement.principal不包含定义...”在删除它并检查intellisense中的可用选项时,还没有类似的命令可用 – ModS 2014-09-03 23:42:00

2

可以使用lockoutTime属性,但是,它并不一定微不足道。该属性有用户被锁定的时间。因此,如果您的域名拥有单一锁定政策,则可以搜索每个人的搜索值,其值大于或等于(UTC Now - Lockout Duration)。

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

如果您的域名有永久锁定(例如您必须申请一个帐号解锁),您可以搜索大于零。