2014-09-03 73 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)。

如果您通過細粒度密碼策略有多個鎖定策略,那麼這不是那麼容易,因爲您需要以每個用戶爲基礎計算它。

如果您的域名有永久鎖定(例如您必須申請一個帳號解鎖),您可以搜索大於零。