【问题标题】:Get User Account Status (Locked/Unlocked) from Active Directory on C-Sharp / C#从 C-Sharp / C# 上的 Active Directory 获取用户帐户状态(锁定/解锁)
【发布时间】:2009-04-03 23:58:40
【问题描述】:

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

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

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

【问题讨论】:

    标签: c# active-directory


    【解决方案1】:

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

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

    【讨论】:

    【解决方案2】:

    发现这个,它比我过去做的多一点(找不到确切的 sn-ps),虽然关键是根据你的用户的锁定时间进行目录搜索和限制回来。此外,对于特定用户,您可以使用其他属性进一步限制您的搜索。我相信上面的代码项目链接具有特定的逻辑(用于搜索限制)。

    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/

    【讨论】:

    • 谢谢 Joshua,但不幸的是,我已经在网上看到的您的解决方案实现了来自 .Net 2.0 及更高版本的类,例如: HostSecurityManager.DomainPolicy 属性注意:此属性是 . NET 框架 2.0 版。
    • 啊,抱歉,没看到 1.1 激动地回答这个问题。
    【解决方案3】:

    在看到 .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());
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多