我正在尝试检索计算机名称列表以及它们上次从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;
}
如果我使用像LDP这样的工具查询AD,我可以看到该属性存在并填充了数据。 我怎样才能获得这些信息?
答案 0 :(得分:11)
使用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);
}
答案 1 :(得分:5)
**处理从DirectoryEntry检索到的属性'lastLogonTimestamp'的方法是将其转换为IADSLargeInteger
自: http://www.dotnet247.com/247reference/msgs/31/159934.aspx **
为这些类型返回的__ComObject是IADsLargeInteger 数值,以及SecurityDescriptors的IADsSecurityDescriptor。
您可以在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开发人员支持
答案 2 :(得分:3)
尝试使用IADsLargeInteger(Source)
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);
}
答案 3 :(得分:1)
原始问题的简单答案是访问搜索结果中的属性:
sr.Properties["lastLogonTimestamp"][0].ToString()
DateTime.FromFileTimeUTC(long.Parse(sr.Properties["lastLogonTimestamp"][0].ToString()))
获取日期时间值
我遇到类似的问题,我可以访问lastLogonTimestamp
中的SearchResult
属性并获取索引结果中的值,但在使用SearchResult.GetDirectoryEntry()
之后我无法访问 DirectoryEntry 上的lastLogonTimestamp
属性的有效结果。
是否有其他人因DirectoryEntry
返回SearchResult.GetDirectoryEntry()
与lastLogonTimestamp
属性相关的问题而遇到此问题?