从C-Sharp / C上的Active Directory获取用户帐户状态(已锁定/已解锁)

时间:2009-04-03 23:58:41

标签: c# active-directory

我需要找到一种方法来检查Active Directory UserAccount是否已锁定其帐户。

我在Windows 2000 AD中尝试过userAccountControl属性但是当我强制帐户被锁定时(通过尝试登录到为该特定用户提供错误密码的工作站),该属性不会更改字节而且我可以通过使用半神制造的ADExplorer.exe实用程序来判断 - > Russinovich先生

我在3.5 Framework中看到他们使用方法.InvokeGet(“userLockedOut”);但我试图在.Net Framework 1.1中编写的企业应用程序中执行此操作,并且没有机会使用更新的(仅当您考虑建议)。

3 个答案:

答案 0 :(得分:3)

这是一个包含Active Directory内容的所有信息的链接......

http://www.codeproject.com/KB/system/everythingInAD.aspx

答案 1 :(得分:2)

发现这一点,它比我过去做的多一点(找不到确切的片段),虽然关键是进行目录搜索并根据返回的用户的锁定时间进行限制。此外,对于特定用户,您可以使用其他属性进一步限制搜索。上面的codeproject链接具有我认为的特定逻辑(用于搜索限制)。

class Lockout : IDisposable
{
  DirectoryContext context;
  DirectoryEntry root;
  DomainPolicy policy;

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

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

    this.root = domain.GetDirectoryEntry();
    this.policy = new DomainPolicy(this.root);      
  }

  public void FindLockedAccounts()
  {
    //default for when accounts stay locked indefinitely
    string qry = "(lockoutTime>=1)";

    TimeSpan duration = this.policy.LockoutDuration;

    if (duration != TimeSpan.MaxValue)
    {
      DateTime lockoutThreshold =
        DateTime.Now.Subtract(duration);

      qry = String.Format(
        "(lockoutTime>={0})",
        lockoutThreshold.ToFileTime()
        );
    }

    DirectorySearcher ds = new DirectorySearcher(
      this.root,
      qry
      );

    using (SearchResultCollection src = ds.FindAll())
    {
      foreach (SearchResult sr in src)
      {
        long ticks =
          (long)sr.Properties["lockoutTime"][0];

        Console.WriteLine(
          "{0} locked out at {1}",
          sr.Properties["name"][0],
          DateTime.FromFileTime(ticks)
          );
      }
    }
  }

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

此帖子中提取了代码:http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/5e0fadc2-f27b-48f6-a6ac-644e12256c67/

答案 2 :(得分:0)

在看到.NET 1.1之后,检查一下这个帖子:http://forums.asp.net/t/434077.aspx,使用过滤器中的锁定时间仍然可以解决问题。

特别是在线程中(在提供大量语法的较大代码之后):

(&(objectClass=user)(objectCategory=person)(lockoutTime>=1)); 

另外一件事,事实证明,如果您使用的是.NET v.1.1,那么S.DS会正确地将Integer8转换为长整数(不适用于1.0) - 这意味着您可以取消反思代码(在帖子中):

//use the filter from above

SearchResultCollection src = ds.FindAll();  

foreach(SearchResult sr in src)

{

     DateTime lockoutTime = DateTime.FromFileTime((long)sr.Properties["lockoutTime][0]);

     Response.Output.Write("Locked Out on: {0}", lockoutTime.ToString());

}