Dave,
This script seems to do exactly what I was looking for.
I've worn your first book out (I actually have two copies: one at work and one at home). If this is the kind of useful stuff I can find in your second book, I need to buy it, too.
Thank you!
-Jason
-----Original Message-----
From: Dave Roth [mailto:[EMAIL PROTECTED]]
Sent: Wednesday, December 25, 2002 3:29 AM
To: 'DePriest, Jason R.'; 'Steven Manross'; Perl-Win32-Admin ([EMAIL PROTECTED])
Subject: RE: Win32::AdminMisc - user flag USER_LOGON_HOURS
My "belief" is the correct belief as per the Win32 documentation. I also
believe that you guys are not taking into account your timezone. The
logon hours stored in the account profile is based on GMT.
I am attaching the DumpAccount.pl script from my second book (
http://www.roth.net/books/handbook/). It will dump the entire account
information including logon hours *properly formatted* for your
timezone.
Note that the script requires Win32::API::Prototype (
http://www.roth.net/perl/packages/win32-api-prototype.ppd). You could
modify the script to only use Win32::API easily enough.
The script yields logon hours displayed as:
logon hours: Sunday: 00-23
Monday: 00-23
Tuesday: 00-23
Wednesday: 00-23
Thursday: 00-23
Friday: 00-23
Saturday: 00-23
The root of the script (regarding logon hours) is:
# Vicious hack to get the time zone
if( ApiLink( 'kernel32.dll',
'DWORD GetTimeZoneInformation( PVOID pTZInfo )' ) )
{
my $pTZInfo = NewString( 200 );
my $Result = GetTimeZoneInformation( $pTZInfo );
if( 0 == $Result || 2 == $Result )
{
$TZOffset = unpack( "l", $pTZInfo ) / 60;
}
}
and
{
# Determine which hours on what days of the week this
user has
# permission to logon
my $DayIndex = 0;
my $BinaryHours = $Value;
my $HourString = unpack( "b*", $BinaryHours );
$Value = "";
# We need to offset the logon hours string by the number
# of hours we are either before or after GMT.
if( 0 > $TZOffset )
{
$TZOffset *= -1;
$HourString =~ s/^(.*)(.{$TZOffset})$/$2$1/;
}
else
{
$HourString =~ s/^(.{$TZOffset})(.*)$/$2$1/;
}
# Now walk through each day and determine what
# hours the user is allowed to log on.
foreach my $Day ( $HourString =~ /.{24}/g )
{
my @Hours;
my $Display = "";
my $Index = 0;
$Day .= "0";
foreach my $HourValue ( split( "", $Day ) )
{
if( $HourValue )
{
if( "" eq $Display )
{
$Display = sprintf( "%02d", $Index );
}
}
else
{
if( "" ne $Display )
{
if( $Display < $Index - 1 )
{
$Display .= sprintf( "-%02d", $Index
- 1 );
}
push( @Hours, $Display );
$Display = "";
}
}
$Index++;
}
$Value .= sprintf( "%- 50s",
"$WEEKDAYS[$DayIndex++]: "
. join( ",", @Hours ) ), "\n";
}
}
-----Original Message-----
From: DePriest, Jason R. [mailto:[EMAIL PROTECTED]]
Sent: Tuesday, December 24, 2002 1:23 PM
To: 'Steven Manross'; Perl-Win32-Admin
([EMAIL PROTECTED])
Subject: RE: Win32::AdminMisc - user flag USER_LOGON_HOURS
Thanks, Steven.
That helped me pull the data out to be a reasonable value (i.e. 21-bytes
instead of 1-byte). I had glanced at the pack/unpack functions but
didn't actually try to use them.
However, I am trying to use the UserGetMiscAttributes module instead of
the UserSetMiscAttributes module.
From your example, I think I'll still have to create a huge switch
statement to get the 1's and 0's into text strings.
-----Original Message-----
From: Steven Manross [ mailto:[EMAIL PROTECTED]]
Sent: Tuesday, December 24, 2002 3:04 PM
To: 'DePriest, Jason R.'; Perl-Win32-Admin
([EMAIL PROTECTED])
Subject: RE: Win32::AdminMisc - user flag USER_LOGON_HOURS
I don't know why but contrary to Dave's belief, I had to set this up
this way to make it work, where the first line is the last few hours on
Sunday and then the next lines are Monday, Tuesday, etc...
%Logon_Hours = ('special' =>
[(1,0,0,0,0,0,0,
0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,
0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,
0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,
0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,
0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,
0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,
0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,
)],
'normal' =>
[(1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
)],
);
my $packed_hours = pack ( 'b*' ,
join('',@{$Logon_Hours{$hours_identifier}}) ) ;
if (Win32::AdminMisc::UserSetMiscAttributes ($pdc, $username,
USER_LOGON_HOURS =>
$packed_hours )) {
print " Succeeded setting Logon Hours for $username!\n";
} else {
print " Failed setting Logon Hours for $username!\nERROR:
",Win32::GetLastError(),"\n";
}
Steven
-----Original Message-----
From: DePriest, Jason R. [ mailto:[EMAIL PROTECTED]]
Sent: Tuesday, December 24, 2002 1:55 PM
To: Perl-Win32-Admin ([EMAIL PROTECTED])
Subject: Win32::AdminMisc - user flag USER_LOGON_HOURS
Dave Roth's documentation and website say this value points to a 21-byte
(168-bit) binary string in which each bit represents one hour of the
week.
Has anyone bothered to parse this flag out into english? The only way I
can think of is to write a pseudo-switch statement with a 168 'if'
statements that push the results into an array.
Plus, if I 'ord' the value from the flag (and no restrictions are set),
I get 255 and not 2E+167.
Thank you!
Jason R DePriest
