Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chriss Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Win32::AdminMisc question 3

Status
Not open for further replies.

Stiddy

IS-IT--Management
Dec 5, 2001
781
US
Platform - Windows NT 4.0 server sp6a
Perl version - 5.6.1 build 633

I am looking for a module that can access user account information. I was hoping Dave Roth's Win32::AdminMisc was my answer but have not figured it out yet. I need to query for all users in a domain. Then figure out the expiration date of the account for each user. If the user is not expired, then great, but if so I got to do some work with the account. Any ideas??? Thanks....Oh, I have also already looked into Win32::NetAdmin module, but could not see where it was my answer either...
 

use Win32::AdminMisc

# retrieve all of the local users
Win32::AdminMisc::GetUsers('','',\@users) or
die "Unable to get users: $!\n";

# get their attributes and print them
foreach $user (@users){
Win32::AdminMisc::UserGetMiscAttributes('',$user,\%attribs) or
warn "Unable to get attrib: $!\n";
print join(":",$user,
'*',
$attribs{USER_USER_ID},
$attribs{USER_PRIMARY_GROUP_ID},
'',
$attribs{USER_COMMENT},
$attribs{USER_FULL_NAME},
$attribs{USER_HOME_DIR_DRIVE}."\\".
$attribs{USER_HOME_DIR},
localtime($attribs{USER_ACCT_EXPIRES}),
''),"\n";
}





haunter@battlestrata.com
 
Haunter your a genius...Thanks for the help. Here is what I have.

use Win32::NetAdmin;
use Win32::AdminMisc;

#### Get the PDC for the domain
Win32::NetAdmin::GetDomainController("", "TESTDOM" , $PDC);

#### retrieve all of the local users
Win32::NetAdmin::GroupGetMembers($PDC, Students, \@users) or die ("Unable to get users: $!\n");

#### get their attributes and print them
foreach $user (@users){
Win32::AdminMisc::UserGetMiscAttributes('',$user,\%attribs) or warn "Unable to get attrib: $!\n";
print join(" ",$user,
$attribs{USER_HOME_DIR},
localtime($attribs{USER_ACCT_EXPIRES}),''),"\n";
}
##end

My output looks like this:
UserA \\testdlspdc\SHARED\UserA 0 0 0 31 6 103 4 211 1
UserB \\testdlspdc\shared\UserB 0 0 0 9 6 103 3 189 1
UserC \\testdlspdc\shared\UserC 0 0 0 15 6 103 2 195 1
UserD \\testdlspdc\shared\UserD 0 0 0 23 6 103 3 203 1
UserE \\testdlspdc\shared\UserE 0 0 0 24 6 103 4 204 1
UserF \\testdlspdc\shared\UserF 0 0 0 2 5 103 1 152 1

Basically I am trying to write a script that will get all members of a global group called students. I then need to loop through every user and look for accounts that are expired + 60days. If the account meets that expired + 60days, then take full control over that users shared drive, delete the folder and all contents, then delete the user account and write to a logfile that all the work is done. And finally loop to the next user. On ant given day I have about 7-8000 user accounts which need to be processed through this script. This script will run on the PDC as a AT job daily. Where I get confused is on the localtime part. How do I get expired + 60 days out of the output?

Currently the users expiration dates are;

USERA - 07-30-03
USERB - 07-08-03
USERC - 07-14-03
USERD - 07-22-03
USERE - 07-23-03
USERF - 06-01-03
 
localtime +(60*(24*(60*60))) = 60 days from now

HTH
Paul

It's important in life to always strike a happy medium, so if you see someone with a crystal ball, and a smile on their face ...
 
Please forgive my ignorance but I have tried PaulTEG's suggestion of localtime so many different ways. For example:


$t = localtime +(60*(24*(60*60))); print "$t";

but only come up with things like:
Time::tm=ARRAY(0x1ab51e0)

What am I doing wrong?
 
localtime () returns an array of time components.

I was in a bit of a hurry, apologies

If you convert your date to a time value (no of seconds since the epoch), add 60*24*60*60 seconds, and then run a localtime function on that, you can find the bits you need 60 days on

(@date}=localtime($yourvalue + 60*60*60*24);
$date[4]++; #month based at 0 add 1;
$date[5]+=1900; # year starts at 1900
$mydate = sprintf("%0.2d"$date[4])."-".sprintf("%0.2d", $date[3])."-".sprintf("0.2d", substr $date[5],2,2);

This should give you your date in the format you have it, though I would suggest if you're comparing date strings, always use YYYYMMDD, or else just use the native time format


You could also lookup the data::manip module

HTH
Paul



It's important in life to always strike a happy medium, so if you see someone with a crystal ball, and a smile on their face ...
 
PaulTEG...I have the following:
Win32::AdminMisc::UserGetMiscAttributes('',$user,\%attribs) or warn ("Unable to get attrib: $!\n");
(@userexpdate) = localtime ($attribs{USER_ACCT_EXPIRES});
(@userexpdateplussixty}=localtime($userexpdate + 60*60*60*24);
$userexpdateplussixty[4]++; #month based at 0 add 1;
$userexpdateplussixty[5]+=1900; # year starts at 1900
$userexpdateplussixty = sprintf("%0.2d"$userexpdateplussixty[4])."-".sprintf("%0.2d", $userexpdateplussixty[3])."-".sprintf("0.2d", substr $userexpdateplussixty[5],2,2);
#################end
recieving this error:

D:\scripts>get_user_attribs.pl
Scalar found where operator expected at D:\scripts\get_user_attribs.pl line 30,
near ""%0.2d"$userexpdateplussixty"
(Missing operator before $userexpdateplussixty?)
syntax error at D:\scripts\get_user_attribs.pl line 27, near "@userexpdatepluss
xty}"
syntax error at D:\scripts\get_user_attribs.pl line 30, near ""%0.2d"$userexpda
eplussixty"
Unmatched right curly bracket at D:\scripts\get_user_attribs.pl line 31, at end
of line
Execution of D:\scripts\get_user_attribs.pl aborted due to compilation errors.
################end

Any ideas. Ive tried modifing the code but haven't been successful. Thanks for your time!!
 
I finally got something like this to work:

foreach $user (@users){
#### Get todays date
(@today_date) = localtime;
$today_date[4]++; #month based at 0 add 1;
$today_date[5]+=1900; # year starts at 1900
Win32::AdminMisc::UserGetMiscAttributes('',$user,\%attribs) or warn ("Unable to get attrib: $!\n");
(@userexpdate) = localtime ($attribs{USER_ACCT_EXPIRES});
$userexpdate[4]++; #month based at 0 add 1;
$userexpdate[5]+=1900; # year starts at 1900
print "$user $today_date[5]$today_date[4]$today_date[3] $userexpdate[5]$userexpdate[4]$userexpdate[3]\n";
}
################end

my output:
Use of uninitialized value in concatenation (.) or string at D:\scripts\test.pl
line 29.
RAAC7033 2003613 19001
HLAM5896 2003613 200368
TAAM2396 2003613 2003615
EVAM1220 2003613 2003714
LVAD3429 2003613 2003615
THAM0113 2003613 2003731
JHAM5860 2003613 2003519
AHAM6800 2003613 2003730
RBAM0662 2003613 2003619
CPBM3850 2003613 2003812
KOAM1993 2003613 200367
DHAM2228 2003613 2003615
RCAM9339 2003613 2003721
KWAM4429 2003613 2003624
RSAM1557 2003613 2003117
BRAM2448 2003613 2003616
JWAM1247 2003613 2003109
##############end

How do I get ride of the Use of uninitialized value in concatenation (.) or string error. And how would I get the column for $userexpdate to always be 7 charaters in length? Also, still could not get the $yourvalue + 60*60*60*24) part to work.
 
Can you post your script in full, where's line 29.

The concat empty string - looks like there's a fault in your first call of userdate, because its coming up with 190001.

Your 7 digit query is a little strange, consider 21-Dec-03 --> 20031231 - 8 digits

Paul

It's important in life to always strike a happy medium, so if you see someone with a crystal ball, and a smile on their face ...
 
here is my whole script:

#!D:/perl/bin/perl -w
use Win32::NetAdmin;
use Win32::AdminMisc;
use Time::Localtime;

#### Get the domain controller for the domain
Win32::NetAdmin::GetDomainController('', 'TADLP0' , $PDC);

#### retrieve all of the local users
Win32::NetAdmin::GroupGetMembers($PDC, 'Students', \@users) or die ("Unable to get users: $!\n");

#### get their attributes and print them
#open (MY_USERS, ">d:/scripts/all_students.log") or die ("Unable to open logfiles: $!\n");
#open (DELETED, ">>d:/scripts/all_students_deleted.log") or die ("Unable to open logfiles: $!\n");
foreach $user (@users){
#### Get todays date
(@today_date) = localtime;
$today_date[4]++; #month based at 0 add 1;
$today_date[5]+=1900; # year starts at 1900
Win32::AdminMisc::UserGetMiscAttributes('',$user,\%attribs) or warn ("Unable to get attrib: $!\n");
#### Get users account expiration date
(@userexpdate) = localtime ($attribs{USER_ACCT_EXPIRES});
$userexpdate[4]++; #month based at 0 add 1;
$userexpdate[5]+=1900; # year starts at 1900
print "$user $today_date $userexpdate[5]$userexpdate[4]$userexpdate[3]\n";
# This is where I am trying to write
# If ($today_date = $userexpdate + 60 days) {
# delete users home directory and all subfiles
# delete user and write to DELETED file
# } end subroutine and loop to next user account
} ###end

The error is on line 25
 
Stiddy,

Is the account RAAC7033 set to never expire perchance? You may have to check for this before converting the date. I can't test this because I don't currently have an NT/2K box in my network.

Also this line
print "$user $today_date $userexpdate[5]$userexpdate[4]$userexpdate[3]\n";
change to
print "$user $today_date $userexpdate[5]".sprintf("%0.2d",$userexpdate[4]).sprintf("%0.2d",$userexpdate[3])."\n";
to ensure you get the eight digit date you need for comparison


HTH
Paul

It's important in life to always strike a happy medium, so if you see someone with a crystal ball, and a smile on their face ...
 
PaulTEG, Yes that accout RAAC7033 is set to never expire as will many others. Is that what is giving me the 'Use of uninitialized value in concatenation (.) or string error?' If so, I guess I would have to write something that states something like:

Win32::AdminMisc::UserGetMiscAttributes('',$user,\%attribs) or warn ("Unable to get attrib: $!\n");
#### Get users account expiration date
(@userexpdate) = localtime ($attribs{USER_ACCT_EXPIRES});
if ($useraccount == ''){
###do nothing} else {###lets check the expiration date}


while something like that work. Is that the best way to do that. Also, As mentioned before, I have about 7-8000 user accounts that are going to loop through this script daily. Is this the best way to do it. Currently all of the users names will be held in memory, should I write them to a text file first, and then read in the text file line by line?
 
I have something like this:

#!D:/perl/bin/perl -w

use Win32::NetAdmin;
use Win32::AdminMisc;
use Time::Localtime;

#### Get the domain controller for the domain
Win32::NetAdmin::GetDomainController('', 'TESTDOM' , $PDC);

#### retrieve all of the local users
Win32::NetAdmin::GroupGetMembers($PDC, 'Students', \@users) or die ("Unable to get users: $!\n");

#### get their attributes and print them
#open (MY_USERS, ">d:/scripts/all_students.log") or die ("Unable to open logfiles: $!\n");
#open (DELETED, ">>d:/scripts/all_students_deleted.log") or die ("Unable to open logfiles: $!\n");
foreach $user (@users){
#### Get todays date
(@today_date) = localtime;
$today_date[4]++; #month based at 0 add 1;
$today_date[5]+=1900; # year starts at 1900


#### Get users account expiration date
Win32::AdminMisc::UserGetMiscAttributes('',$user,\%attribs) or warn ("Unable to get attrib: $!\n");
(@userexpdate) = localtime ($attribs{USER_ACCT_EXPIRES});
$userexpdate[4]++; #month based at 0 add 1;
$userexpdate[5]+=1900; # year starts at 1900
if ($userexpdate eq 'TIMEQ_FOREVER') {
&Never_expires;
} else {
print "$user $today_date[5]".sprintf("%0.2d",$today_date[4]).sprintf("%0.2d",$today_date[3]). "$userexpdate[5]".sprintf("%0.2d",$userexpdate[4]).sprintf("%0.2d",$userexpdate[3])."\n\n";
}
# This is where I am trying to write
# If ($today_date = $userexpdate + 60 days) {
# delete users home directory and all subfiles
# delete user and write to DELETED file
# } end subroutine and loop to next user account
}

sub Never_expires {
print "$user will never expire\n";
}

###### END

But the 'TIMEQ_FOREVER' part is not working. See any problems?
 
Stiddy,

You're already getting 19001 returned as the date for non-expiry, I'd use that ... just coz I'm lazy, and its a date in the past, that won't reoccur
TIMEQ_FOREVER is that a constant value thats returned from the function?, this may be an integer value that you need to set as a constant in your code.

As I said, earlier your were getting "19001" being returned, this may have been causing the error, though the sprintf (if you use it) function should now change this to 19000100 (adding 1 to the month in the code). If you check for this value, you should be coming up bandy

HTH
Paul
 
PaulTEG,

Even when I use 19000100 I still get 'Use of uninitialized valuse in sprintf at line 31'.

Here's my code:
#!D:/perl/bin/perl -w

use Win32::NetAdmin;
use Win32::AdminMisc;
use Time::Localtime;

#### Get the domain controller for the domain
Win32::NetAdmin::GetDomainController('', 'TESTDOM' , $PDC);

#### retrieve all of the local users
Win32::NetAdmin::GroupGetMembers($PDC, 'Students', \@users) or die ("Unable to get users: $!\n");

#### get their attributes and print them
#open (MY_USERS, ">d:/scripts/all_students.log") or die ("Unable to open logfiles: $!\n");
#open (DELETED, ">>d:/scripts/all_students_deleted.log") or die ("Unable to open logfiles: $!\n");
foreach $user (@users){
#### Get todays date
(@today_date) = localtime;
$today_date[4]++; #month based at 0 add 1;
$today_date[5]+=1900; # year starts at 1900


#### Get users account expiration date
Win32::AdminMisc::UserGetMiscAttributes('',$user,\%attribs) or warn ("Unable to get attrib: $!\n");
(@userexpdate) = localtime ($attribs{USER_ACCT_EXPIRES});
$userexpdate[4]++; #month based at 0 add 1;
$userexpdate[5]+=1900; # year starts at 1900
if ($userexpdate == '19000100') {
&Never_expires;
} else {
print "$user $today_date[5]".sprintf("%0.2d",$today_date[4]).sprintf("%0.2d",$today_date[3]). "$userexpdate[5]".sprintf("%0.2d",$userexpdate[4]).sprintf("%0.2d",$userexpdate[3])."\n";
}
# This is where I am trying to write
# If ($today_date = $userexpdate + 60 days) {
# delete users home directory and all subfiles
# delete user and write to DELETED file
# } end subroutine and loop to next user account
}

sub Never_expires {
print "$user will never expire\n";
}
 
Try this
Code:
  (@userexpdate) = localtime ($attribs{USER_ACCT_EXPIRES});
        $userexpdate[4]++; #month based at 0 add 1;
        $userexpdate[5]+=1900; # year starts at 1900
        if $userexpdate[3]="" {
           $userdate[3]=0
        }
        $my_userexpdate = $userexpdate[5].sprintf("%0.2d",$userexpdate[4]).sprintf("%0.2d", $userexpdate[3]);
        if ($my_userexpdate == '19000100') {
        &Never_expires;
        } else {
           print "$user $today_date[5]".sprintf("%0.2d",$today_date[4]).sprintf("%0.2d",$today_date[3])." $my_userexpdate\n";
        }

I may have lost the indentations, but I'm sure you get the jist of it

Paul
 
That works fine, but I still get some errors. I think it has something to do with the @userexpdate[3]. I will work on trying to figure it out somemore. Also, I have never used the sprintf function. I will research it, If you have time can you explain %0.2d? Also, How do I get $today_date + 60 days. I know you gave me the formula earlier, but I couldn't get it to work like everything else. haha. Below is my output which contains the errors. Line 28 is the:

if ($userexpdate[3] eq "") {$userexpdate[3] = 0;}#I changed a little

#### Output
JFAM2687 20030617 20031030
TCAM8154 20030617 20030819
ITAM6440 20030617 20030517
RGAM6789 20030617 20031015
JWAM6774 20030617 20030629
DHAM8036 20030617 20031005
RRAM8636 20030617 20030911
MTAM4912 20030617 20030616
Use of uninitialized value in string eq at A:\test.pl line 28.
FBAC4001 will never expire
JMAM2112 20030617 20030627
TRAM0144 20030617 20031024
MFAM1346 20030617 20031002
MBAM0307 20030617 20031130
RDAM2328 20030617 20031002
MSAM7583 20030617 20031002
CNAM4956 20030617 20030612
MPAM3440 20030617 20030811
Use of uninitialized value in string eq at A:\test.pl line 28.
TKAC4152 will never expire
MKAM4775 20030617 20030826
ANADD495 20030617 20030615
AKAM3106 20030617 20030618
AAAD0582 20030617 20030617
TCAM5468 20030617 20030619
NSAM5262 20030617 20030925
ARAM8293 20030617 20030624
APAM2450 20030617 20031016
RSAM0997 20030617 20030615
FBAM7693 20030617 20030809
JPAD3458 20030617 20031113
SMAM5545 20030617 20031018
ACAM7195 20030617 20030524
BLAM8528 20030617 20030621
JMAM2943 20030617 20030519
ALAM9696 20030617 20030517
JBAM7291 20030617 20030724
BSAM4540 20030617 20030530
SSAM8321 20030617 20030519
CJAM0601 20030617 20030722
EBAM0206 20030617 20030616
Use of uninitialized value in string eq at A:\test.pl line 28.
JCAC5196 will never expire
LRAM4375 20030617 20031014
KOAM6743 20030617 20030613
KPAM6189 20030617 20030619
JMAM9975 20030617 20030517
CEAM6411 20030617 20030922
JRAM4418 20030617 20031002
MBAM8337 20030617 20030816
 
Stiddy,

sprintf("%0.2d", "3") formats "3" to "03"
sprintf("%0.4d", "3") formats "3" to "0003"
If you're familiar with VB it's like the format command.

I said I didn't have a NT+ box, so I couldn't test, and it looks like it'll need a different test
try
Code:
   if (undef $userexpdate[3]) {$userexpdate[3]=0}
todays date + 60 should be
#!/usr/bin/perl

$now=time;
$then=$now+(60*24*60*60);
@now1=localtime($now);
@then1=localtime($then);
$now1[5]+=1900;
$now1[4]++;
$then1[5]+=1900;
$then1[4]++;
$now_str=$now1[5].sprintf("%0.2d",$now1[4]).sprintf("%0.2d",$now1[3]);
$then_str=$then1[5].sprintf("%0.2d",$then1[4]).sprintf("%0.2d",$then1[3]);
print "$now_str\t$then_str\n";
HTH Paul
 
PaulTEG:

Here is what we got:
#!D:/perl/bin/perl -w

use Win32::NetAdmin;
use Win32::AdminMisc;
use Time::Localtime;

#### Get the domain controller for the domain
Win32::NetAdmin::GetDomainController('', 'TADLP0' , $PDC);

#### retrieve all of the local users
Win32::NetAdmin::GroupGetMembers($PDC, 'Students', \@users) or die ("Unable to get users: $!\n");

#### get their attributes and print them
$count = 0;
foreach $user (@users){
$count++;
#### Get todays date
$now=time;
@now1=localtime($now);
$now1[5]+=1900;
$now1[4]++;
$now_str=$now1[5].sprintf("%0.2d",$now1[4]).sprintf("%0.2d",$now1[3]);

#### Get users account expiration date
Win32::AdminMisc::UserGetMiscAttributes('',$user,\%attribs) or warn ("Unable to get attrib: $!\n");
(@userexpdate) = localtime ($attribs{USER_ACCT_EXPIRES});
$userexpdate[4]++;
$userexpdate[5]+=1900;
if ($userexpdate[3] eq "") {$userexpdate[3] = 0;}
$my_userexpdate = $userexpdate[5].sprintf("%0.2d",$userexpdate[4]).sprintf("%0.2d", $userexpdate[3]);
if ($my_userexpdate == 19000100) {&Never_expires;}

#### User account expiration date plus sixty days
$then=$my_userexpdate+(60*24*60*60);
@then1=localtime($then);
$then1[5]+=1900;
$then1[4]++;
$then_str=$then1[5].sprintf("%0.2d",$then1[4]).sprintf("%0.2d",$then1[3]);
print "$user $now_str $my_userexpdate $then_str $count\n";
}

sub Never_expires {
print "$user will never expire\n";
}
####END

All is working well except the +60 days part. My output is as such:

TWAD4188 will never expire
TWAD4188 20030618 19000100 19701007 1
JMAM1422 20030618 20030817 19701019 2
TGAM4420 20030618 20030822 19701019 3
KSAM8548 20030618 20030826 19701019 4
RMAM0550 20030618 20030618 19701019 5
JSAM6198 20030618 20030801 19701019 6
KHAM9582 20030618 20030823 19701019 7
CTAM5836 20030618 20030618 19701019 8
LDAM3247 20030618 20030729 19701019 9
JVAM7184 20030618 20031121 19701019 10
DRAM7735 20030618 20030606 19701019 11
AEAM9128 20030618 20030619 19701019 12
JAAM7073 20030618 20030816 19701019 13
ERAM7558 20030618 20030922 19701019 14
CAAM3808 20030618 20030517 19701019 15
SCAM6032 20030618 20030801 19701019 16
DHAM8918 20030618 20030909 19701019 17
SLAM5465 20030618 20031130 19701019 18
CVAM1718 20030618 20030524 19701019 19

Do you see the problem. I am still hacking at it...
 
Incorporate these bits again
Code:
$now1[5]+=1900;
$now1[4]++;

-Paul
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top