1

Here is some sample code I have that finds all computer objects in an OU. When I print out the property fields, I get a System.__ComObject for several of the values such as lastLogon, lastLogonTimestamp, pwdLastSet, uSNChanged, etc. I assume these are all date-ish type values of some sort.

How do I get the date value out of it? I'd like a c# solution not a powershell solution such as this: https://sweeneyops.wordpress.com/2012/06/11/active-directory-timestamp-conversion-through-powershell/

Thanks

using (DirectoryEntry entry = new DirectoryEntry("LDAP://" + ou))
{
    using (DirectorySearcher searcher = new DirectorySearcher(entry))
    {
        searcher.Filter = ("(objectClass=computer)");
        searcher.SizeLimit = int.MaxValue;
        searcher.PageSize = int.MaxValue;

        foreach (SearchResult result in searcher.FindAll())
        {
            DirectoryEntry computer = result.GetDirectoryEntry();

            foreach(string propName in computer.Properties.PropertyNames)
            {
                foreach(object value in computer.Properties[propName])
                {
                    Console.WriteLine($"{propName}: {value}");
                }
            }
        }
    }
}

I know there is a long inside of the object that I can use DateTime.FromFileTime(longType) to get the date out of it.

ohmusama
  • 4,159
  • 5
  • 24
  • 44

2 Answers2

2

Already answered here: there's no need to add a reference to a COM Types library if you need only this interface.

To work with COM type you can define interface in your own code:

[ComImport, Guid("9068270b-0939-11d1-8be1-00c04fd8d503"), InterfaceType(ComInterfaceType.InterfaceIsDual)]
internal interface IAdsLargeInteger
{
    long HighPart
    {
        [SuppressUnmanagedCodeSecurity] get; [SuppressUnmanagedCodeSecurity] set;
    }

    long LowPart
    {
        [SuppressUnmanagedCodeSecurity] get; [SuppressUnmanagedCodeSecurity] set;
    }
}

and use it the same way:

var largeInt = (IAdsLargeInteger)directoryEntry.Properties[propertyName].Value;
var datelong = (largeInt.HighPart << 32) + largeInt.LowPart;
var dateTime = DateTime.FromFileTimeUtc(datelong);

There's also a good article, explaining how to interpret ADSI data

Mikhail Tumashenko
  • 1,683
  • 2
  • 21
  • 28
1

What you need to do is add a COM reference to the "Active DS Type Library"

Then the following code will make a date time out of one of the fields, for example "pwdLastSet"

IADsLargeInteger largeInt = (IADsLargeInteger)computer.Properties["pwdLastSet"][0];
long datelong = (((long)largeInt.HighPart) << 32) + largeInt.LowPart;
DateTime pwSet = DateTime.FromFileTimeUtc(datelong);
ohmusama
  • 4,159
  • 5
  • 24
  • 44