The foreach block at callout A in Listing 1 parses the command-line
arguments, assigning the user-assigned arguments to corresponding scalar
variables. If a username or database filename is missing, the two lines after
the foreach block set the $sUsername and $sPasswordDB scalars to the script
defaults.
The if block at B executes when the user specifies the f=hostname
option in the command line. This option retrieves the account password from the
corresponding hostname record in the password database. Inside the if block, the
script calls the ReadRecord subroutine, passing it the $sPasswordDB (the
filename) and $sFetchPasswordFor (the hostname) scalars.
Let's look at how the script passes these parameters to the ReadRecord
subroutine, which Listing 3 shows. The first statement in the ReadRecord
subroutine includes the @_ symbol, which is Perl's special subroutine argument
array. Perl has no concept of named formal parameters. Instead, Perl passes
values to all subroutines via the built-in @_ array. The @_ array's first
element, @_[0], contains the first parameter. Its second element, @_[1],
contains the second parameter, and so on. Typically, a script copies the
contents of the @_ array into locally scoped variables. In the ReadRecord
subroutine, the first statement copies $sPasswordDB and $sFetchPasswordFor into
the locally scoped variables of $db and $server. (You'll see this type of
initialization statement in most of the script's subroutines.)
The ReadRecord subroutine then opens the database for read and uses the
grep command (which finds matching elements in a list) to find the record
containing $server, initializing @dbrecord with the result. After closing the
database, the subroutine uses the split command to extract the current password
(the second field of the data record) from @dbrecord. The subroutine then
returns the password to $sPassword at B in Listing 1.
The print statement at B signals the end of the if block. The script prints
the username and password information on the console of the person executing the
script.
The if block at C changes the $sUsername password on one or all hosts based
on the use of the c=hostname and c=ALL options. The process begins when
the script tests the contents of $sChangePasswordOn. If the scalar contains a
value, the script checks the scalar to see whether it contains the string ALL
and initializes the @hosts array with the list of hostnames the CreateHostList
subroutine creates. (CreateHostList uses Perl's map function to extract the
server names from the password database.) If $sChangePasswordOn doesn't contain
the string ALL, the block initializes the @hosts array with $sChangePasswordOn,
a single hostname.
Before any password changes take place, the script performs a backup of the
password database. The script then seeds Perl's rand function, which the script
uses to generate random passwords in the Password subroutine.
The foreach loop at D carries out the password changes. The loop begins by
assigning the first element of the @hosts array to the $host scalar. ReadRecord
retrieves the current password from the password database, and the script stores
it in $sOldPassword. Next, the script uses the Password subroutine to generate a
new, random, eight-character alphanumeric password and stores it in
$sNewPassword. The script uses Perl's time function to obtain the current
timestamp and stores it in $t. The script passes the hostname, username, old
password, and new password to AdminMisc's UserChangePassword function. If
UserChangePassword succeeds (indicated by a return value of 1), $bResult remains
TRUE; otherwise $bResult is set to FALSE.
The main body of the script then uses the WriteRecord subroutine to update
the password database. On success, WriteRecord updates all the fields (except
hostname) of the appropriate server record. In the event UserChangePassword
fails, WriteRecord updates only the status field. The script then proceeds to
the next host in the @hosts array. After the script exhausts the @hosts list, it
falls out of the foreach loop and change block.
The final block at E generates the formatted report as defined by the r
option in the command line. This option uses the SortPasswordDB and CreateReport
subroutines to sort the database. The CreateReport subroutine uses a format
definition to produce the report.
Automate Your Chores
PWManager.pl demonstrates how you can use Perl to automate an important, but
time-consuming NT systems administration task. If you perform an NT
administration chore that you automate with a script, drop me an email. I'm
interested in your solutions; if you can't figure out a solution, I might be
able to come up with one.
End of Article
Prev. page
1
2
[3]
next page -->