pwdLastSet and other Active Directory Date types

  • Thread starter Thread starter Jerry Ham
  • Start date Start date
J

Jerry Ham

Has anyone been able to get the "date" properties (pwdLastSet, lastLogon,
etc.) from Active Directory using JUST the native .Net tools (no com interop
with activeds)? When I try to do that, I get strange results. Consider the
following simple code:

(for this a .Net reference is set to System.DirectoryServices)
Private Function Test(ByVal sLDAPPath As String)
Dim de As New DirectoryEntry(sLDAPPath)
Dim sr As SearchResult
Dim ds As New DirectorySearcher(de)
Dim lTemp As Long
ds.PropertiesToLoad.Add("pwdLastSet")
ds.PropertiesToLoad.Add("lastLogon")
sr = ds.FindOne
If sr Is Nothing Then
'not found
Else
lTemp = sr.Properties.Item("pwdLastSet")(0)
End If

End Function

With MY user ID, lTemp ends up with 127133852422713849. That's fine, I can
use a DateTime.FromFileTime, but it comes back with a date that is about a
day off from what I get back using the interop (not just the UTC time
difference). I get similar results on other accounts (sometimes it is very
close, other times it is WAY off. When I use the Microsoft sample "Active
Directory Browser" (adsvw.exe) it shows this value should be
127133856717681145. Again, similar results on other accounts.

Samples:
above code adsvw.exe
127129877390570772 126626200214730160
126625284477162600 126625284477162600 (yes, this one comes out
the SAME!!!)

I know I can use something like this:

Private Sub Test(ByVal sLDAPPath As String)
Dim objUser As ActiveDs.IADsUser
objUser = GetObject(sLDAPPath)
Dim dt As Date = objUser.PasswordLastChanged()

End Sub

And it will work (as long as I referenced ActiveDS), but I do not really
want to ship the Interop.ActiveDS.dll along (or use COM) for this.

Anyone "been there, done that - solved it" that would share?
Thanks!
Jerry
 
Has anyone been able to get the "date" properties (pwdLastSet, lastLogon,
etc.) from Active Directory using JUST the native .Net tools (no com interop
with activeds)? When I try to do that, I get strange results.

With MY user ID, lTemp ends up with 127133852422713849. That's fine, I can
use a DateTime.FromFileTime, but it comes back with a date that is about a
day off from what I get back using the interop (not just the UTC time
difference).

One problem might be that the "pwdLastSet" and other time values are
stored in LargeInteger (8-byte unsigned integer) values, which .NET
doesn't natively support (as far as I know) - Int64 is always signed.

Here's an MSDN article on how to deal with 8-Byte integer values in
..NET languages:

http://msdn.microsoft.com/library/d...ds/large_integer_property_type.asp?frame=true

Marc
================================================================
Marc Scheuner May The Source Be With You!
Bern, Switzerland m.scheuner(at)inova.ch
 
Jerry,

No need to import activeds interop assembly in VB.NET, VB supports late binding at the language level.

This should work.

Dim dt As Date = de.NativeObject.PasswordLastChanged()

Willy.
 
Thanks Mark! I spent a good part of the day searching the web and never
found that link.

Jerry
 
Thanks Willy!

That does indeed work. I am guessing the performance won't be all that bad
since System.DirectoryServices is already using ADSI and COM behind the
scenes. I will try it and see which has better perf - using a reference to
the activeds library or doing it the way you pointed out.

Jerry
 
Jerry Ham said:
Thanks Willy!

That does indeed work. I am guessing the performance won't be all that bad
since System.DirectoryServices is already using ADSI and COM behind the
scenes. I will try it and see which has better perf - using a reference to
the activeds library or doing it the way you pointed out.

Jerry

Sure, System.DirectoryServices uses ADSI COM behind the scene and IADsUser is a Dispatch interface anyway, so you don't need to
worry about performance.

Willy.
 
Back
Top