As you may have noticed, there are two different types of dates returned
by AD... one can automatically be resolved by using the
Win32::OLE::Variant module, but the other is represented as a quadword
(or "long integer"). The attribute value, as represented by Win32::OLE,
is a hash containing two entries, the high longword and the low
longword. I've never been quite sure how to convert them to a date...
until now...

So, if anyone is interested... here's a procedure that accepts the two
halves of the quadword and returns a value compatible with that returned
by time() and ready to feed to localtime() or gmtime().

sub msqtime2perl { # MicroSoft QuadTime to Perl
  my ($high,$low) = @_;
  return ((unpack("L",pack("L",$low)) + (unpack("L",pack("L",$high)) *
(2 ** 32))) / 10000000) - 11644473600;
}

Usage:

  my $user =
Win32::OLE->GetObject('LDAP://CN=name,CN=container,DC=domain,DC=tld');
  my $d =
localtime(msqtime2perl($user->{'lastLogon'}->{'HighPart'},$user->{'lastL
ogon'}->{'LowPart'}));
  print "Last Logon Time: $d\n";

The reason I pack and unpack each part is to make sure they're unsigned.
If you have a better way, let me know. Also, I could probably hardcode
the 2**32 value for speed, but this is a bit more self-documenting. (I
tried <<32 but that didn't seem to work.)  The core of the formula I
found in a VBscript in January's "Windows Scripting Solutions". The
"11644473600" epoch-delta I found by trial and error on my own. I
thought I'd do a Google search on the value for verification, and sure
enough it's a well-known value in the U*ix world.

You'll probably want to add functionality to detect situations where
both the low and high parts are zero (meaning "never"?). There are also
times where only the high part is zero... is this a delta time? 

Matt Stum
Information/Infrastructure Services Consultant
Ball State University

_______________________________________________
Perl-Win32-Admin mailing list
[EMAIL PROTECTED]
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs

Reply via email to