简体   繁体   English

如何列出所有计算机以及他们最后一次登录AD?

[英]How to list all computers and the last time they were logged onto in AD?

I am trying to retrieve a list of Computer Names and the date they were last logged onto from Active Directory and return them in a datatable. 我正在尝试检索计算机名称列表以及它们上次从Active Directory登录的日期,并将它们返回到数据表中。 Getting the names is easy enough but when I try to add the "lastLogon" or "lastLogonTimestamp" like shown below, the only values I get for the lastLogonTimestamp is "System._ComObject" 获取名称很容易但是当我尝试添加“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;
}

If I query AD using a tool like LDP I can see that the property exists and is populated with data. 如果我使用像LDP这样的工具查询AD,我可以看到该属性存在并填充了数据。 How can I get at this info? 我怎样才能获得这些信息?

It'd be easier to use the ComputerPrincipal class and a PrincipalSearcher from System.DirectoryServices.AccountManagement. 使用ComputerPrincipal类和System.DirectoryServices.AccountManagement中的PrincipalSearcher会更容易。

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);
}

**The way to treat the property 'lastLogonTimestamp' retrieved from a DirectoryEntry is to convert it to IADSLargeInteger **处理从DirectoryEntry检索到的属性'lastLogonTimestamp'的方法是将其转换为IADSLargeInteger

from: http://www.dotnet247.com/247reference/msgs/31/159934.aspx ** 来自: http//www.dotnet247.com/247reference/msgs/31/159934.aspx **

The __ComObject returned for these types is IADsLargeInteger for the numeric values, and IADsSecurityDescriptor for SecurityDescriptors. 为这些类型返回的__ComObject是数值的IADsLargeInteger和SecurityDescriptors的IADsSecurityDescriptor。

You can include a reference on the COM tab to Active DS Type Lib and get the definition for these interfaces or manually define them. 您可以在COM选项卡上包含对Active DS Type Lib的引用,并获取这些接口的定义或手动定义它们。 Here is a sample: 这是一个示例:

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);
        }
    }

}

David Stucki Microsoft Developer Support David Stucki微软开发人员支持

Try using IADsLargeInteger ( Source ) 尝试使用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);
}

A simple answer to the original question is to access the property on your search result: 对原始问题的简单回答是访问搜索结果中的属性:

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

DateTime.FromFileTimeUTC(long.Parse(sr.Properties["lastLogonTimestamp"][0].ToString())) to obtain a datetime value DateTime.FromFileTimeUTC(long.Parse(sr.Properties["lastLogonTimestamp"][0].ToString()))获取日期时间值

I'm having a similar issue, I can access the lastLogonTimestamp property in the SearchResult and obtain a value in the indexed result but after using SearchResult.GetDirectoryEntry() I am not able to access a valid result for the lastLogonTimestamp property on the DirectoryEntry . 我有一个类似的问题,我可以访问SearchResultlastLogonTimestamp属性并获取索引结果中的值,但在使用SearchResult.GetDirectoryEntry()我无法访问DirectoryEntrylastLogonTimestamp属性的有效结果。

Has anyone else run into this issue with the DirectoryEntry returned from SearchResult.GetDirectoryEntry() as it relates to access to the lastLogonTimestamp property? 有没有其他人使用SearchResult.GetDirectoryEntry()返回的DirectoryEntry遇到此问题,因为它与访问lastLogonTimestamp属性有关?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM