2013-04-02 54 views
0

首先,請,如果我沒有使用正確的術語原諒我。糾正我無論我使用錯誤的術語。搜索多個域服務器的用戶lastLogon屬性全部

目標是編程方式檢索一個給定用戶名的lastLogon日期。

我們有什麼,我相信這是一個森林;兩個AD服務器 - adserver01.aa.mycompany.comadserver02.aa.mycompany.com

我使用Microsoft的ADExplorer從第三臺機器連接到這些服務器以檢查對象。在那裏,我看到一些用戶在adserver01中有LastLogon日期,但不在adserver02中。例如,對於某些用戶,lastLogon的值在adserver02中爲0x0,而在adserver01中爲有效日期。

我到目前爲止已經爲Windows窗體應用程序開發的代碼,如果只有一個AD服務器參與工作正常。如何檢查兩臺服務器併爲lastLogon日期屬性返回非零值(如果可用)?

 private static string GetLastActivityDate(string UserName) 
    { 
     string domainAndUserName = String.Format(@"LDAP://aa.mycompany.com/CN={0},OU=CLIENT_PROD,OU=clients.mycompany.com,DC=aa,DC=mycompany,DC=com", UserName); 
     string OUAdminUserName = "abc"; 
     string OUAdminPassword = "xyz"; 
     AuthenticationTypes at = AuthenticationTypes.Secure; 
     DateTime lastActivityDate; 
     string returnvalue; 
     long lastLogonDateAsLong; 


     using (DirectoryEntry entryUser = new DirectoryEntry(domainAndUserName, OUAdminUserName, OUAdminPassword, at)) 
     using (DirectorySearcher mysearcher = new DirectorySearcher(entryUser)) 
      try 
      { 
       using (SearchResultCollection results = mysearcher.FindAll()) 
       { 
        if (results.Count >= 1) 
        { 
         DirectoryEntry de = results[0].GetDirectoryEntry(); 
         lastLogonDateAsLong = GetInt64(de, "lastLogon"); 
         try 
         { 
          if (lastLogonDateAsLong != -1) 
          { 
           lastActivityDate = DateTime.FromFileTime(lastLogonDateAsLong); 
           returnvalue = lastActivityDate.ToString(); 
          } 
          else 
          { 
           returnvalue = "-Not available-"; 
          } 
         } 
         catch (System.ArgumentOutOfRangeException aore) 
         { 
          returnvalue = "Not available"; 
         } 
        } 
        else 
        { 
         returnvalue = string.Empty; 
        } 
       } 
      } 
      catch (System.DirectoryServices.DirectoryServicesCOMException dsce) 
      { 
       returnvalue = "- Not available -"; 
      } 


     return returnvalue; 
    } 

謝謝。

編輯:

private static Int64 GetInt64(DirectoryEntry entry, string attr) 
    { 

     DirectorySearcher ds = new DirectorySearcher(
      entry, 
      String.Format("({0}=*)", attr), 
      new string[] { attr }, 
      SearchScope.Base 
      ); 

     SearchResult sr = ds.FindOne(); 

     if (sr != null) 
     { 
      if (sr.Properties.Contains(attr)) 
      { 
       return (Int64)sr.Properties[attr][0]; 
      } 
     } 
     return -1; 
    } 

忘記提到,AD模式,結構等,看起來完全相同的兩個服務器。

+1

如果它工作正常,一個..then替換從域或URL解析,你要麼從config文件讀取或可傳遞變量/硬編碼的LDAP連接刺痛..或基本具備列表並傳遞列表對象到您的帕拉姆的方法和在for循環內就可以完成同樣的事情有一些小的硬編碼值更改參數 – MethodMan

回答

3

檢查這個帖子 http://www.codeproject.com/Articles/19181/Find-LastLogon-Across-All-Windows-Domain-Controlle

我有同樣的問題,但但只有一個域, 我用下面的代碼,但是我正在檢查所有用戶的lastLogin解決它

public static Dictionary<string, DateTime> UsersLastLogOnDate() 
    { 
     var lastLogins = new Dictionary<string, DateTime>(); 
     DomainControllerCollection domains = Domain.GetCurrentDomain().DomainControllers; 
     foreach (DomainController controller in domains) 
     { 
      try 
      { 
       using (var directoryEntry = new DirectoryEntry(string.Format("LDAP://{0}", controller.Name))) 
       { 
        using (var searcher = new DirectorySearcher(directoryEntry)) 
        { 
         searcher.PageSize = 1000; 
         searcher.Filter = "(&(objectClass=user)(!objectClass=computer))"; 
         searcher.PropertiesToLoad.AddRange(new[] { "distinguishedName", "lastLogon" }); 
         foreach (SearchResult searchResult in searcher.FindAll()) 
         { 
          if (searchResult.Properties.Contains("lastLogon")) 
          { 
           var lastLogOn = DateTime.FromFileTime((long)searchResult.Properties["lastLogon"][0]); 
           var username = Parser.ParseLdapAttrValue(searchResult.Properties["distinguishedName"][0].ToString()); 
           if (lastLogins.ContainsKey(username)) 
           { 
            if (DateTime.Compare(lastLogOn, lastLogins[username]) > 0) 
            { 
             lastLogins[username] = lastLogOn; 
            } 
           } 
           else 
           { 
            lastLogins.Add(username, lastLogOn); 
           } 
          } 
         } 
        } 

       } 


      } 
      catch (System.Runtime.InteropServices.COMException comException) 
      { 
       // Domain controller is down or not responding 
       Log.DebugFormat("Domain controller {0} is not responding.",controller.Name); 
       Log.Error("Error in one of the domain controllers.", comException); 
       continue; 
      } 
     } 
     return lastLogins; 
    } 

在代碼之上,您可以使用以下命令獲取林中的所有域。

Forest currentForest = Forest.GetCurrentForest(); 
DomainCollection domains = currentForest.Domains; 
foreach(Domain domain in domains) 
{ 
    // check code above 
} 
1

有可能是一個更簡單的方法?實際上,還有另一個屬性lastLogonTimestamp,添加了我認爲的2003域級別,它試圖在整個域中爲上次登錄保留一個單一的一致值。唉,它有一個奇怪的複製時間模式,可能會過兩週過時。

+0

你是正確的現有工作的代碼,我的服務器管理員告訴我說14天的不同步是Windows 2003中的一個已知問題。 – FMFF