2013-04-02 3 views
0

먼저 올바른 용어를 사용하지 않으면 용서해주세요. 잘못된 용어를 사용하는 곳이면 어디든지 수정하십시오.여러 도메인 서버에서 사용자의 lastLogon 속성 검색

목적은 프로그래밍 방식으로 주어진 사용자 이름의 lastLogon 날짜를 검색하는 것입니다.

우리는 내가 숲이라고 믿는 것을 가지고 있습니다. - adserver01.aa.mycompany.comadserver02.aa.mycompany.com

과 같은 두 개의 AD 서버 Microsoft의 ADExplorer를 사용하여 개체를 검사하는 제 3의 컴퓨터에서이 서버에 연결되었습니다. lastLogon 날짜가 adserver01 인 사용자가 있지만 adserver02은 볼 수 없습니다. 예를 들어, lastLogon의 값은 adserver02에서 0x0이며 일부 사용자의 경우 유효한 날짜 인 adserver01입니다.

Windows Forms 응용 프로그램까지 개발 한 코드는 하나의 AD 서버 만 있으면 잘 작동합니다. lastLogon 날짜 속성에 대해 두 서버를 모두 확인하고 사용 가능한 경우 0이 아닌 값을 반환하려면 어떻게합니까?

 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

는 도메인이나 URL에서 구문 분석 당신이 중 하나 .config 파일에서 읽거나 그이 전달 될 수있는 변수 /를 사용하여 하드 코딩 LDAP 연결 고통을 교체 ... 또는 기본적으로이 ..then 하나 잘 작동하는 경우 목록 을 입력하고 해당 목록 개체를 매개 변수로 메서드에 전달하고 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

더 간단한 방법이있을 수 있습니까? 실제로 마지막 로그인을 위해 도메인 전체에 단일 값을 유지하려고 시도하는 2003 도메인 수준이 추가 된 lastLogonTimestamp라는 또 다른 속성이 있습니다. 아아, 기괴한 복제 시간 패턴을 가지며 최신 2 주일이 될 수 있습니다.

+0

에 약간의 하드 코딩 된 값 변경을 사용하여 기존 작업 코드에서 동일한 작업을 수행 할 수 있습니다. Windows 2003에서는 14 일간의 비 동기화 문제가 알려진 문제입니다. – FMFF

관련 문제