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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/716128/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 22:15:28  来源:igfitidea点击:

Get User Account Status (Locked/Unlocked) from Active Directory on C-Sharp / C#

c#active-directory

提问by monoco

I need to find a way to check if an Active Directory UserAccount has his account locked or not.

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

I've tried userAccountControl property in a Windows 2000 AD but that property does not change a byte when I force an account to get locked (by trying to log on to a workstation providing the wrong password for that specific user) And I can tell by using ADExplorer.exeutility made by semi-god -> Mr. Russinovich

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

I've seen that in the 3.5 Framework they use the method .InvokeGet("userLockedOut"); but I'm trying to do this in a Enterprise Application that was written in .Net Framework 1.1 and there's no chance of using newer ones (just if you thought of suggesting so).

我已经看到在 3.5 框架中他们使用方法 .InvokeGet("userLockedOut"); 但我正在尝试在用 .Net Framework 1.1 编写的企业应用程序中执行此操作,并且没有机会使用较新的应用程序(如果您想这么建议的话)。

回答by bytebender

Here is a link with all the info on Active Directory stuff...

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

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

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

回答by Joshua

Found this, it is a little more than I have done in the past (can't find exact snippets) though the key is doing a directory search and limiting based on the lockouttime for your user(s) that are returned. Additionally for a particular user, you can limit your search further using additional properties. The codeproject link above has that particular logic (for search limiting) I believe.

发现这个,它比我过去所做的多一点(找不到确切的片段),尽管关键是根据返回的用户的锁定时间进行目录搜索和限制。此外,对于特定用户,您可以使用其他属性进一步限制您的搜索。我相信上面的 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();
    }
  }
}

Code was pulled from this post: http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/5e0fadc2-f27b-48f6-a6ac-644e12256c67/

代码是从这篇文章中提取的:http: //social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/5e0fadc2-f27b-48f6-a6ac-644e12256c67/

回答by Joshua

After seeing the .NET 1.1, check this thread out: http://forums.asp.net/t/434077.aspx, using the lockouttime in the filter should still do the trick.

看到 .NET 1.1 后,请查看此线程:http: //forums.asp.net/t/434077.aspx,在过滤器中使用锁定时间仍然可以解决问题。

Specifically in the thread (after the larger code post which provides alot of the syntax):

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

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

One other thing, it turns out that if you are using .NET v.1.1, then S.DS converts the Integer8 to the long integer correctly for you (does not work with 1.0) - which means you can do away with reflection code (in the post):

另一件事,事实证明,如果您使用的是 .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());

}