Как перечислить все компьютеры и последний раз, когда они вошли в AD? - PullRequest
3 голосов
/ 21 октября 2009

Я пытаюсь получить список имен компьютеров и дату их последнего входа в систему из Active Directory и вернуть их в виде данных. Получить имена достаточно просто, но когда я пытаюсь добавить «lastLogon» или «lastLogonTimestamp», как показано ниже, единственные значения, которые я получаю для lastLogonTimestamp, это «System._ComObject»

public DataTable GetListOfComputers(string domainName)
{
  DirectoryEntry entry = new DirectoryEntry("LDAP://DC=" + domainName + ",DC=com");
  DirectorySearcher search = new DirectorySearcher(entry);
  string query = "(objectclass=computer)";
  search.Filter = query;

  search.PropertiesToLoad.Add("name");
  search.PropertiesToLoad.Add("lastLogonTimestamp");

  SearchResultCollection mySearchResultColl = search.FindAll();

  DataTable results = new DataTable();
  results.Columns.Add("name");
  results.Columns.Add("lastLogonTimestamp");

  foreach (SearchResult sr in mySearchResultColl)
  {
    DataRow dr = results.NewRow();
    DirectoryEntry de = sr.GetDirectoryEntry();
    dr["name"] = de.Properties["Name"].Value;
    dr["lastLogonTimestamp"] = de.Properties["lastLogonTimestamp"].Value;
    results.Rows.Add(dr);
    de.Close();
  }

  return results;
}

Если я запрашиваю AD с помощью такого инструмента, как LDP, я вижу, что свойство существует и заполнено данными. Как я могу получить эту информацию?

Ответы [ 4 ]

11 голосов
/ 21 октября 2009

Было бы проще использовать класс ComputerPrincipal и PrincipalSearcher из System.DirectoryServices.AccountManagement.

PrincipalContext pc = new PrincipalContext(ContextType.Domain, domainName);
PrincipalSearcher ps = new PrincipalSearcher(new ComputerPrincipal(pc));
PrincipalSearchResult<Principal> psr = ps.FindAll();
foreach (ComputerPrincipal cp in psr)
{
    DataRow dr = results.NewRow();
    dr["name"] = cp.Name;
    dr["lastLogonTimestamp"] = cp.LastLogon;    
    results.Rows.Add(dr);
}
5 голосов
/ 27 марта 2012

** Способ обработки свойства lastLogonTimestamp, полученного из DirectoryEntry, состоит в преобразовании его в IADSLargeInteger

из: http://www.dotnet247.com/247reference/msgs/31/159934.aspx**

__ComObject, возвращаемый для этих типов, является IADsLargeInteger для числовые значения и IADsSecurityDescriptor для SecurityDescriptors.

Вы можете включить ссылку на вкладку COM в Active DS Type Lib и получить определение для этих интерфейсов или определить их вручную. Вот образец:

using System;
using System.DirectoryServices;
using System.Runtime.InteropServices;

//This is the managed definition of this interface also found in
ActiveDs.tlb
[ComImport]
[Guid("9068270B-0939-11D1-8BE1-00C04FD8D503")]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
internal interface IADsLargeInteger
{
    [DispId(0x00000002)]
    int HighPart{get; set;}
    [DispId(0x00000003)]
    int LowPart{get; set;}
}

class Class1
{
    [STAThread]
    static void Main(string[] args)
    {
        DirectoryEntry entry = new
DirectoryEntry("LDAP://cn=user,cn=users,dc=domain,dc=com");
        if(entry.Properties.Contains("lastLogon"))
        {
            IADsLargeInteger li =
(IADsLargeInteger)entry.Properties["lastLogon"][0];    
            long date = (long)li.HighPart << 32 | (uint)li.LowPart;
            DateTime time = DateTime.FromFileTime(date);
            Console.WriteLine("Last logged on at: {0}", time);
        }
    }

}

Дэвид Стуки Поддержка разработчиков Microsoft

3 голосов
/ 21 октября 2009

Попробуйте использовать IADsLargeInteger ( Источник )

DirectoryEntry user = DirectoryEntry("LDAP://" + strDN);
if (user.Properties.Contains("lastlogontimestamp"))
{
  // lastlogontimestamp is a IADsLargeInteger
  IADsLargeInteger li = (IADsLargeInteger) 
  user.Properties["lastlogontimestamp"][0];
  long lastlogonts = 
      (long)li.HighPart << 32 | (uint)li.LowPart;
  user.Close();
  return DateTime.FromFileTime(lastlogonts);
}
1 голос
/ 27 марта 2012

Простой ответ на оригинальный вопрос - получить доступ к свойству в результатах поиска:

sr.Properties["lastLogonTimestamp"][0].ToString()

DateTime.FromFileTimeUTC(long.Parse(sr.Properties["lastLogonTimestamp"][0].ToString())) для получения значения даты и времени

У меня похожая проблема, я могу получить доступ к свойству lastLogonTimestamp в SearchResult и получить значение в индексированном результате, но после использования SearchResult.GetDirectoryEntry() я не могу получить доступ к действительному результату для lastLogonTimestamp свойство в DirectoryEntry .

Кто-нибудь еще сталкивался с этой проблемой с DirectoryEntry, возвращаемым с SearchResult.GetDirectoryEntry(), поскольку он связан с доступом к свойству lastLogonTimestamp?

...