Date math with UTC Coded Time
Date math with UTC Coded Time
am 27.01.2009 21:14:30 von Glenn.Deans
I'm tasked with obtaining a list of all systems in AD where the
modifyTimeStamp is older than 90 days. Fairly easy to re-use some code
and do some simple date math, right? I seem to be able to access the
value from an ADO query, but it doesn't always display properly, even if
I use Win32::OLE::Variant instead of dereferencing the variable like so:
use Win32::OLE;
$Win32::OLE::Warn = 3;
use Win32::OLE::Variant;
use constant ADS_SCOPE_SUBTREE => 2;
use constant ADS_CHASE_REFERRALS_EXTERNAL => 0x40;
$objConn = Win32::OLE->new('ADODB.Connection');
$objCmd = Win32::OLE->new('ADODB.Command');
$objConn->{Provider} = 'ADsDSOObject';
$objConn->Open('Active Directory Provider');
die Win32::OLE->LastError() if Win32::OLE->LastError( );
$objCmd->{ActiveConnection} = $objConn;
$objCmd->{CommandText} = "Select Name,modifyTimeStamp from
\'LDAP://DC=foobar,DC=com\' Where objectClass=\'Computer\'";
$objCmd->SetProperty("Properties", 'Page Size', 1000);
$objCmd->SetProperty("Properties", 'Searchscope',
ADS_SCOPE_SUBTREE);
$objCmd->SetProperty("Properties", 'Chase referrals',
ADS_CHASE_REFERRALS_EXTERNAL);
my $objRecSet = $objCmd->Execute();
die Win32::OLE->LastError() if Win32::OLE->LastError( );
until ($recset->EOF){
$modified = $recset->Fields('modifyTimeStamp')->Value;
print "Modified=$modified\n";
# displays
$recset->MoveNext;
}
It seems any dates from last year come out as 1/9/2009 2:22:05 AM. I'm
not sure what I'm doing wrong, but maybe someone could point it out to
me? Then once that is corrected, how can you easily tell if it's > 90
days since it doesn't seem to be an epoch time?
.................................
Kind regards
Glenn Deans
Architect
Siemens IT Solutions and Services
Urbana, OH USA
_______________________________________________
ActivePerl mailing list
ActivePerl@listserv.ActiveState.com
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs
RE: Date math with UTC Coded Time
am 03.02.2009 18:59:58 von Glenn.Deans
Can anyone give me some direction for handling the UTC Coded time? I
think I'm just missing something obvious, but I just can't get this into
a useable format for doing any kind of date math.
.................................
Kind regards
Glenn Deans
Architect
Siemens IT Solutions and Services
Urbana, OH USA
-----Original Message-----
From: activeperl-bounces@listserv.ActiveState.com
[mailto:activeperl-bounces@listserv.ActiveState.com] On Behalf Of Deans,
Glenn (IT Solutions US)
Sent: Tuesday, January 27, 2009 3:15 PM
To: activeperl@listserv.ActiveState.com
Subject: Date math with UTC Coded Time
I'm tasked with obtaining a list of all systems in AD where the
modifyTimeStamp is older than 90 days. Fairly easy to re-use some code
and do some simple date math, right? I seem to be able to access the
value from an ADO query, but it doesn't always display properly, even if
I use Win32::OLE::Variant instead of dereferencing the variable like so:
use Win32::OLE;
$Win32::OLE::Warn = 3;
use Win32::OLE::Variant;
use constant ADS_SCOPE_SUBTREE => 2;
use constant ADS_CHASE_REFERRALS_EXTERNAL => 0x40;
$objConn = Win32::OLE->new('ADODB.Connection');
$objCmd = Win32::OLE->new('ADODB.Command');
$objConn->{Provider} = 'ADsDSOObject';
$objConn->Open('Active Directory Provider');
die Win32::OLE->LastError() if Win32::OLE->LastError( );
$objCmd->{ActiveConnection} = $objConn;
$objCmd->{CommandText} = "Select Name,modifyTimeStamp from
\'LDAP://DC=foobar,DC=com\' Where objectClass=\'Computer\'";
$objCmd->SetProperty("Properties", 'Page Size', 1000);
$objCmd->SetProperty("Properties", 'Searchscope',
ADS_SCOPE_SUBTREE);
$objCmd->SetProperty("Properties", 'Chase referrals',
ADS_CHASE_REFERRALS_EXTERNAL);
my $objRecSet = $objCmd->Execute();
die Win32::OLE->LastError() if Win32::OLE->LastError( );
until ($recset->EOF){
$modified = $recset->Fields('modifyTimeStamp')->Value;
print "Modified=$modified\n";
# displays
$recset->MoveNext;
}
It seems any dates from last year come out as 1/9/2009 2:22:05 AM. I'm
not sure what I'm doing wrong, but maybe someone could point it out to
me? Then once that is corrected, how can you easily tell if it's > 90
days since it doesn't seem to be an epoch time?
.................................
Kind regards
Glenn Deans
Architect
Siemens IT Solutions and Services
Urbana, OH USA
_______________________________________________
ActivePerl mailing list
ActivePerl@listserv.ActiveState.com
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs
_______________________________________________
ActivePerl mailing list
ActivePerl@listserv.ActiveState.com
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs
Re: Date math with UTC Coded Time
am 03.02.2009 19:54:45 von lyle
DateTime.pm
Deans, Glenn (IT Solutions US) wrote:
> Can anyone give me some direction for handling the UTC Coded time? I
> think I'm just missing something obvious, but I just can't get this into
> a useable format for doing any kind of date math.
>
> ................................
> Kind regards
>
> Glenn Deans
> Architect
> Siemens IT Solutions and Services
> Urbana, OH USA
>
> -----Original Message-----
> From: activeperl-bounces@listserv.ActiveState.com
> [mailto:activeperl-bounces@listserv.ActiveState.com] On Behalf Of Deans,
> Glenn (IT Solutions US)
> Sent: Tuesday, January 27, 2009 3:15 PM
> To: activeperl@listserv.ActiveState.com
> Subject: Date math with UTC Coded Time
>
> I'm tasked with obtaining a list of all systems in AD where the
> modifyTimeStamp is older than 90 days. Fairly easy to re-use some code
> and do some simple date math, right? I seem to be able to access the
> value from an ADO query, but it doesn't always display properly, even if
> I use Win32::OLE::Variant instead of dereferencing the variable like so:
>
> use Win32::OLE;
> $Win32::OLE::Warn = 3;
> use Win32::OLE::Variant;
> use constant ADS_SCOPE_SUBTREE => 2;
> use constant ADS_CHASE_REFERRALS_EXTERNAL => 0x40;
>
> $objConn = Win32::OLE->new('ADODB.Connection');
> $objCmd = Win32::OLE->new('ADODB.Command');
> $objConn->{Provider} = 'ADsDSOObject';
> $objConn->Open('Active Directory Provider');
> die Win32::OLE->LastError() if Win32::OLE->LastError( );
> $objCmd->{ActiveConnection} = $objConn;
> $objCmd->{CommandText} = "Select Name,modifyTimeStamp from
> \'LDAP://DC=foobar,DC=com\' Where objectClass=\'Computer\'";
> $objCmd->SetProperty("Properties", 'Page Size', 1000);
> $objCmd->SetProperty("Properties", 'Searchscope',
> ADS_SCOPE_SUBTREE);
> $objCmd->SetProperty("Properties", 'Chase referrals',
> ADS_CHASE_REFERRALS_EXTERNAL);
> my $objRecSet = $objCmd->Execute();
> die Win32::OLE->LastError() if Win32::OLE->LastError( );
> until ($recset->EOF){
> $modified = $recset->Fields('modifyTimeStamp')->Value;
> print "Modified=$modified\n";
> # displays
> $recset->MoveNext;
> }
>
> It seems any dates from last year come out as 1/9/2009 2:22:05 AM. I'm
> not sure what I'm doing wrong, but maybe someone could point it out to
> me? Then once that is corrected, how can you easily tell if it's > 90
> days since it doesn't seem to be an epoch time?
>
> ................................
> Kind regards
>
> Glenn Deans
> Architect
> Siemens IT Solutions and Services
> Urbana, OH USA
>
> _______________________________________________
> ActivePerl mailing list
> ActivePerl@listserv.ActiveState.com
> To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs
> _______________________________________________
> ActivePerl mailing list
> ActivePerl@listserv.ActiveState.com
> To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs
>
>
_______________________________________________
ActivePerl mailing list
ActivePerl@listserv.ActiveState.com
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs
Re: Date math with UTC Coded Time
am 04.02.2009 01:53:43 von Bill Luebkert
Deans, Glenn (IT Solutions US) wrote:
> Can anyone give me some direction for handling the UTC Coded time? I
> think I'm just missing something obvious, but I just can't get this into
> a useable format for doing any kind of date math.
I know nothing of ADO, but given an epoch time or a UTC time, it shouldn't
be that hard to convert. You'll need to find out why you're getting the
strange value for $modified back before you can fix it though.
> until ($recset->EOF){
> $modified = $recset->Fields('modifyTimeStamp')->Value;
> print "Modified=$modified\n";
> # displays
> $recset->MoveNext;
> }
>
> It seems any dates from last year come out as 1/9/2009 2:22:05 AM. I'm
> not sure what I'm doing wrong, but maybe someone could point it out to
> me? Then once that is corrected, how can you easily tell if it's > 90
> days since it doesn't seem to be an epoch time?
Once you have your times in epoch format, it's just simple math to check
for 90 days (90 * 86400 seconds) difference.
Are you literally getting '1/9/2009 2:22:05 AM' back for $modified ?
If so, I have no idea why. I would expect a string like '20090203164851Z'
which you can easily parse into pieces and feed to Time::Local::timegm to
get epoch time.
If not, what are you literally getting ?
_______________________________________________
ActivePerl mailing list
ActivePerl@listserv.ActiveState.com
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs
RE: Date math with UTC Coded Time
am 04.02.2009 19:33:54 von Glenn.Deans
Thanks Bill. I was able to do something like that with the long integer
for pwdLastSet, but I'm having trouble getting a usable value. I can't
seem to figure out what data I'm getting or, I guess, how to access it
properly. If I don't use Win32::OLE::Variant, and mod the code like
below, I get what looks like a reference to a scalar, but the
dereferenced variable doesn't have anything that I would call useful.
OLE & references are definitely my weak point, but I just don't know how
to get anything that I could feed to Date::Time, Date::Calc, Time::Local
or one of the other date modules.
until ($recset->EOF){
$modified = $recset->Fields('modifyTimeStamp')->Value;
print "Modified=$modified ($$modified)\n";
# displays
Modified=Win32::OLE::Variant=SCALAR(0x19c4fbc) (25317948)
$recset->MoveNext;
}
Am I just trying to access the returned value improperly?
Glenn
-----Original Message-----
From: Bill Luebkert [mailto:dbecoll@roadrunner.com]
Sent: Tuesday, February 03, 2009 7:54 PM
To: Deans, Glenn (IT Solutions US)
Cc: activeperl@listserv.ActiveState.com
Subject: Re: Date math with UTC Coded Time
Deans, Glenn (IT Solutions US) wrote:
> Can anyone give me some direction for handling the UTC Coded time? I
> think I'm just missing something obvious, but I just can't get this
into
> a useable format for doing any kind of date math.
I know nothing of ADO, but given an epoch time or a UTC time, it
shouldn't
be that hard to convert. You'll need to find out why you're getting the
strange value for $modified back before you can fix it though.
> until ($recset->EOF){
> $modified = $recset->Fields('modifyTimeStamp')->Value;
> print "Modified=$modified\n";
> # displays
> $recset->MoveNext;
> }
>
> It seems any dates from last year come out as 1/9/2009 2:22:05 AM.
I'm
> not sure what I'm doing wrong, but maybe someone could point it out to
> me? Then once that is corrected, how can you easily tell if it's > 90
> days since it doesn't seem to be an epoch time?
Once you have your times in epoch format, it's just simple math to check
for 90 days (90 * 86400 seconds) difference.
Are you literally getting '1/9/2009 2:22:05 AM' back for $modified ?
If so, I have no idea why. I would expect a string like
'20090203164851Z'
which you can easily parse into pieces and feed to Time::Local::timegm
to
get epoch time.
If not, what are you literally getting ?
_______________________________________________
ActivePerl mailing list
ActivePerl@listserv.ActiveState.com
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs
RE: Date math with UTC Coded Time
am 04.02.2009 20:18:24 von Ken Cornetet
I think maybe this is what you want...
Use Math::BigInt;
############################################################ ############
########
# Convert Microsoft's FILETIME variant into standard Epoch time
############################################################ ############
########
sub ConvertToEpoch {
my $ts = shift;
if( $ts->HighPart == 0 and $ts->LowPart == 0 ) {
return 0;
}
my $hi = Math::BigInt->from_hex( sprintf("0x%x", $ts->HighPart) );
my $lo = Math::BigInt->from_hex( sprintf("0x%x", $ts->LowPart) );
$hi->blsft(32); # shift high order bits left by 32
my $lastlogon = Math::BigInt->new('0');
$lastlogon->badd($hi);
$lastlogon->badd($lo);
# $lastlogon now contains the number of 100 nanosecond intervals since
01/01/1601
$lastlogon->bdiv('10000000'); # convert to seconds
$lastlogon->bsub('11644473600'); # number of seconds between
01/01/1601 and 01/01/1970
return $lastlogon->numify;
}
The reference to the scalar you are getting is in fact an object that
represents a 64 bit integer. The object has methods HighPart and LowPart
which return the high 32 bits and low 32 bits respectively. I use
Math::BigInt to build a BigInt from these two values, then convert to
seconds, then translate from 01/01/1601 to 01/01/1970.
Since the function could be passed 0, and a 32 bit value can't handle
-369 years worth of seconds, I "short circuit" by returning a 0 if a 0
date of zero is passed.
-----Original Message-----
From: activeperl-bounces@listserv.ActiveState.com
[mailto:activeperl-bounces@listserv.ActiveState.com] On Behalf Of Deans,
Glenn (IT Solutions US)
Sent: Wednesday, February 04, 2009 1:34 PM
To: activeperl@listserv.ActiveState.com
Subject: RE: Date math with UTC Coded Time
Thanks Bill. I was able to do something like that with the long integer
for pwdLastSet, but I'm having trouble getting a usable value. I can't
seem to figure out what data I'm getting or, I guess, how to access it
properly. If I don't use Win32::OLE::Variant, and mod the code like
below, I get what looks like a reference to a scalar, but the
dereferenced variable doesn't have anything that I would call useful.
OLE & references are definitely my weak point, but I just don't know how
to get anything that I could feed to Date::Time, Date::Calc, Time::Local
or one of the other date modules.
until ($recset->EOF){
$modified = $recset->Fields('modifyTimeStamp')->Value;
print "Modified=$modified ($$modified)\n";
# displays
Modified=Win32::OLE::Variant=SCALAR(0x19c4fbc) (25317948)
$recset->MoveNext;
}
Am I just trying to access the returned value improperly?
Glenn
-----Original Message-----
From: Bill Luebkert [mailto:dbecoll@roadrunner.com]
Sent: Tuesday, February 03, 2009 7:54 PM
To: Deans, Glenn (IT Solutions US)
Cc: activeperl@listserv.ActiveState.com
Subject: Re: Date math with UTC Coded Time
Deans, Glenn (IT Solutions US) wrote:
> Can anyone give me some direction for handling the UTC Coded time? I
> think I'm just missing something obvious, but I just can't get this
into
> a useable format for doing any kind of date math.
I know nothing of ADO, but given an epoch time or a UTC time, it
shouldn't
be that hard to convert. You'll need to find out why you're getting the
strange value for $modified back before you can fix it though.
> until ($recset->EOF){
> $modified = $recset->Fields('modifyTimeStamp')->Value;
> print "Modified=$modified\n";
> # displays
> $recset->MoveNext;
> }
>
> It seems any dates from last year come out as 1/9/2009 2:22:05 AM.
I'm
> not sure what I'm doing wrong, but maybe someone could point it out to
> me? Then once that is corrected, how can you easily tell if it's > 90
> days since it doesn't seem to be an epoch time?
Once you have your times in epoch format, it's just simple math to check
for 90 days (90 * 86400 seconds) difference.
Are you literally getting '1/9/2009 2:22:05 AM' back for $modified ?
If so, I have no idea why. I would expect a string like
'20090203164851Z'
which you can easily parse into pieces and feed to Time::Local::timegm
to
get epoch time.
If not, what are you literally getting ?
_______________________________________________
ActivePerl mailing list
ActivePerl@listserv.ActiveState.com
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs
_______________________________________________
ActivePerl mailing list
ActivePerl@listserv.ActiveState.com
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs