You don't need to have perl installed on the servers for this. It can be installed there for other purposes, but here only the perl on your local machine will be used. Here is a quick'n'dirty script I use for exactly this purpose. I attach it as well with a .TXT extension. Let me know if you have any problem with it. <<Win32_Lanman_NetUserSetInfo_Change_User_Password_on_all_machines.txt>> # ============================================================================ ====================== # # Win32_Lanman_NetUserSetInfo_Change_User_Password_on_all_machines.PL # Written by Bruno BELLENGER - May 2000 - March 2001 # This script requires two data files. The name of the computer file must be provided on # the command line. This file must contain the names of the machine on which you want to change the # user's password, one machine per line. # The user name for which the password needs to be changed must be provided as second argument. # You will be prompted for the password, which won't be displayed on screen. # # SYNTAX EXAMPLE : perl thisscript.pl computerfile username # # The host file is only required to display a machine's information when pinging it has failed. # Tested on Perl 5.x # ============================================================================ ====================== # use Term::ReadKey; use Win32::Lanman ; use Net::Ping ; if ($ARGV[-1] lt 2) {die "\n*** ERROR ***\nSYNTAX : perl thiscript COMPUTERS_FILE USERNAME\n\t You will be prompted for the password to be assigned.\n" ; } $computerfile = "$ARGV[0]" ; $user = "$ARGV[1]" ; $sessions_number = 0 ; $user_found = 0 ; $pwd_tmp = "$ARGV[2]" ; open(COMPFILE, "$computerfile") or die "Can't open file [$computerfile]"; @WSNAMES=<COMPFILE>; close COMPFILE; open(HOSTS, "hosts") or print ">>>>> HOSTS file couldn't be opened !!! : not a big deal.<<<<< \n"; @HOSTS=<HOSTS>; close HOSTS ; chomp @WSNAMES ; chomp @HOSTS ; $pwd = &getpassword($pwd_tmp) ; ### Enable next line for debugging purpose only : #print "[$pwd]\n" ; ($pwd =~ /^\s*$/) ? ($operation_performed = "REMOVED !") : ($operation_performed = "changed.") ; $i = 0 ; foreach $computer (@WSNAMES) { next if ($computer =~ /^\s*$/) ; chomp $computer ; $i++ ; print "$i. \t" ; if (!($computer =~ m/^#/)) { my $ping = Net::Ping->new("icmp", 2); my $result = $ping->ping($computer); if ($result) { #NetUserEnum($domain, $filter, \@user) #Enums all user on server \\$computer. Only normal accounts will be enumerated. $computer = substr($computer,2,) if (substr($computer,0,2) eq "\\\\") ; #print "-" x 200 , "\n" ; print "Getting user accounts from [\\\\$computer]. Please wait... " ; if(!Win32::Lanman::NetUserEnum("\\\\$computer", &FILTER_NORMAL_ACCOUNT, \@users)) { print "Sorry, something went wrong executing Win32::Lanman::NetUserEnum(\"\\\\$computer\", &FILTER_NORMAL_ACCOUNT, \@users); error: "; # get the error code print Win32::Lanman::GetLastError(); print " : $^E" ; #exit 1; } foreach $usr (@users) { #print "name = ", ${$usr}{'name'}, " " x (30 - length(${$usr}{'name'})), "comment = ", ${$usr}{'comment'}, " " x (80 - length(${$usr}{'comment'})), "full_name = ", ${$usr}{'full_name'}, "\n"; $user_found = 1 if ("\U${$usr}{'name'}" eq "\U$user") ; } if ($user_found) { # NetUserGetInfo syntax : # NetUserGetInfo($server, $user, \%info) # Retrieves information about user $user on server \\$computer. #print "\n" ; if (!Win32::Lanman::NetUserGetInfo("\\\\$computer", "$user", \%userinfo)) { print "Sorry, something went wrong; error: "; # get the error code print Win32::Lanman::GetLastError(); print " : $^E" ; #exit 1; } $userinfo{password} = "$pwd" ; unless (Win32::Lanman::NetUserSetInfo("\\\\$computer", $user, \%userinfo)) { print "Sorry, something went wrong; error: "; # get the error code print Win32::Lanman::GetLastError(); print " : $^E\n"; #exit 1; } else { #print "-" x 200 , "\n" ; print "User account [$computer\\$user\]'s password was successfully $operation_performed\n"; print "-" x 200 , "\n" ; } } else {print "User [$user] not found on [$computer] !.\n"; print "-" x 200 , "\n" ; } # end if ($user_found) -- else } else {@hostlines = () ; print "!" x 200 , "\n" ; @hostlines = grep /$computer/ig, @HOSTS ; chomp @hostlines ; print "[$computer] not found on the network ! @hostlines\n" ; print "!" x 200 , "\n" ; } } else { print "Ignoring the [$computer] entry in [$computerfile] file.\n"; print "-" x 200 , "\n" ; } } #/-------------------------------------------------------------------------- ---------------------------------------------------------------------------- ----------------------------------------/# #/-------------------------------------------------------------------------- ---------------------------------------------------------------------------- ----------------------------------------/# #/-------------------------------------------------------------------------- ---------------------------------------------------------------------------- ----------------------------------------/# sub getpassword { my $pwd1=shift ; if ($pwd1 eq "") { ReadMode( "noecho", STDIN ); print "Please enter pwd :"; $pwd1 = <STDIN>; chop $pwd1 ; print "\n" ; ReadMode ("original", STDIN) ; } ReadMode( "noecho", STDIN ); print "Please confirm password :"; $pwd2 = <STDIN>; chop $pwd2 ; print "\n" ; ReadMode ("original", STDIN) ; ### Enable next line for debugging purpose only : #print "if (\"$pwd1\" ne \"$pwd2\") " ; if ("$pwd1" ne "$pwd2") { print "Passwords do not match !\n" ; &getpassword()}; ### Enable next line for debugging purpose only : #print "$pwd1 $pwd2\n" ; return $pwd1 ; } #/-------------------------------------------------------------------------- ---------------------------------------------------------------------------- ----------------------------------------/# #/-------------------------------------------------------------------------- ---------------------------------------------------------------------------- ----------------------------------------/# #/-------------------------------------------------------------------------- ---------------------------------------------------------------------------- ----------------------------------------/# _____________________________________________ Bruno Bellenger Sr. Network/Systems Administrator -----Original Message----- From: [EMAIL PROTECTED] [SMTP:[EMAIL PROTECTED]] Sent: Wednesday, May 02, 2001 5:35 PM To: [EMAIL PROTECTED] Subject: Mass change of local passwords I recently inherited a network of several hundred NT servers, spread throughout the country, all of which have different passwords for the local administrator account. The username for that account is the same across the board. Not all the passwords are known. I'd like to change both the username and password for the local administrator account on all of these servers (one fell swoop), so they match a new standard. One server at a time would take too long. I figure the only way to do this is via a script; possibly providing my domain admin credentials to access the SAM. As a newbie to Perl, I'm getting no where fast. Can somebody lend assistance? Almost all of the servers have ActivePerl 5.5 installed. P.S. - I've barely started to learn to use modules. Brett Baumer Levi Strauss & Co. Sr. LAN Analyst Global Data Center Operations Phone: (415) 501-5408 Pager: (888) 423-1763
# ================================================================================================== # # Win32_Lanman_NetUserSetInfo_Change_User_Password_on_all_machines.PL # Written by Bruno BELLENGER - May 2000 - March 2001 # This script requires two data files. The name of the computer file must be provided on # the command line. This file must contain the names of the machine on which you want to change the # user's password, one machine per line. # The user name for which the password needs to be changed must be provided as second argument. # You will be prompted for the password, which won't be displayed on screen. # # SYNTAX EXAMPLE : perl thisscript.pl computerfile username # # The host file is only required to display a machine's information when pinging it has failed. # Tested on Perl 5.x # ================================================================================================== # use Term::ReadKey; use Win32::Lanman ; use Net::Ping ; if ($ARGV[-1] lt 2) {die "\n*** ERROR ***\nSYNTAX : perl thiscript COMPUTERS_FILE USERNAME\n\t You will be prompted for the password to be assigned.\n" ; } $computerfile = "$ARGV[0]" ; $user = "$ARGV[1]" ; $sessions_number = 0 ; $user_found = 0 ; $pwd_tmp = "$ARGV[2]" ; open(COMPFILE, "$computerfile") or die "Can't open file [$computerfile]"; @WSNAMES=<COMPFILE>; close COMPFILE; open(HOSTS, "hosts") or print ">>>>> HOSTS file couldn't be opened !!! : not a big deal.<<<<< \n"; @HOSTS=<HOSTS>; close HOSTS ; chomp @WSNAMES ; chomp @HOSTS ; $pwd = &getpassword($pwd_tmp) ; ### Enable next line for debugging purpose only : #print "[$pwd]\n" ; ($pwd =~ /^\s*$/) ? ($operation_performed = "REMOVED !") : ($operation_performed = "changed.") ; $i = 0 ; foreach $computer (@WSNAMES) { next if ($computer =~ /^\s*$/) ; chomp $computer ; $i++ ; print "$i. \t" ; if (!($computer =~ m/^#/)) { my $ping = Net::Ping->new("icmp", 2); my $result = $ping->ping($computer); if ($result) { #NetUserEnum($domain, $filter, \@user) #Enums all user on server \\$computer. Only normal accounts will be enumerated. $computer = substr($computer,2,) if (substr($computer,0,2) eq "\\\\") ; #print "-" x 200 , "\n" ; print "Getting user accounts from [\\\\$computer]. Please wait... " ; if(!Win32::Lanman::NetUserEnum("\\\\$computer", &FILTER_NORMAL_ACCOUNT, \@users)) { print "Sorry, something went wrong executing Win32::Lanman::NetUserEnum(\"\\\\$computer\", &FILTER_NORMAL_ACCOUNT, \@users); error: "; # get the error code print Win32::Lanman::GetLastError(); print " : $^E" ; #exit 1; } foreach $usr (@users) { #print "name = ", ${$usr}{'name'}, " " x (30 - length(${$usr}{'name'})), "comment = ", ${$usr}{'comment'}, " " x (80 - length(${$usr}{'comment'})), "full_name = ", ${$usr}{'full_name'}, "\n"; $user_found = 1 if ("\U${$usr}{'name'}" eq "\U$user") ; } if ($user_found) { # NetUserGetInfo syntax : # NetUserGetInfo($server, $user, \%info) # Retrieves information about user $user on server \\$computer. #print "\n" ; if (!Win32::Lanman::NetUserGetInfo("\\\\$computer", "$user", \%userinfo)) { print "Sorry, something went wrong; error: "; # get the error code print Win32::Lanman::GetLastError(); print " : $^E" ; #exit 1; } $userinfo{password} = "$pwd" ; unless (Win32::Lanman::NetUserSetInfo("\\\\$computer", $user, \%userinfo)) { print "Sorry, something went wrong; error: "; # get the error code print Win32::Lanman::GetLastError(); print " : $^E\n"; #exit 1; } else { #print "-" x 200 , "\n" ; print "User account [$computer\\$user\]'s password was successfully $operation_performed\n"; print "-" x 200 , "\n" ; } } else {print "User [$user] not found on [$computer] !.\n"; print "-" x 200 , "\n" ; } # end if ($user_found) -- else } else {@hostlines = () ; print "!" x 200 , "\n" ; @hostlines = grep /$computer/ig, @HOSTS ; chomp @hostlines ; print "[$computer] not found on the network ! @hostlines\n" ; print "!" x 200 , "\n" ; } } else { print "Ignoring the [$computer] entry in [$computerfile] file.\n"; print "-" x 200 , "\n" ; } } #/----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------/# #/----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------/# #/----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------/# sub getpassword { my $pwd1=shift ; if ($pwd1 eq "") { ReadMode( "noecho", STDIN ); print "Please enter pwd :"; $pwd1 = <STDIN>; chop $pwd1 ; print "\n" ; ReadMode ("original", STDIN) ; } ReadMode( "noecho", STDIN ); print "Please confirm password :"; $pwd2 = <STDIN>; chop $pwd2 ; print "\n" ; ReadMode ("original", STDIN) ; ### Enable next line for debugging purpose only : #print "if (\"$pwd1\" ne \"$pwd2\") " ; if ("$pwd1" ne "$pwd2") { print "Passwords do not match !\n" ; &getpassword()}; ### Enable next line for debugging purpose only : #print "$pwd1 $pwd2\n" ; return $pwd1 ; } #/----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------/# #/----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------/# #/----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------/#