Last updated: 8 Feb 2007
2 hrs.
how to administer a computer
| Type | Advantages | Disadvantages |
|---|---|---|
| Command line |
|
|
| GUI |
|
|
Automation: A. Series of manual tasks -> one task, possibly parameterized B. Task done periodically or at a particular time by person -> periodically executed by computer Scripting: writing utillity programs; focus on speed of coding, ease of use by peers, re-use of OS and other cmds and their output; simplicity in code and data storage/retrieval Scheduling: do something at a specified time, perhaps repeatedly; often use a script the thing to do When to automate: - tedious task - error-prone tasks - promote consistency - increase reliability - conditionally do task - repeatedly do task - many steps in task - many tasks (combine tasks) How to automate? 1. Start simple 2. Know how to do it manually A. Do it manually B. Record the subtasks 3. Review subtasks A. Is there an existing cmd/cmds that can perform function of subtask? B. What is input of subtask? C. What is output of subtask? D. What changes in system due to subtask? 4. Code and test incrementally Tricks of the trade - return codes: check them; provide them in your scripts - provide help on usage - args: options vs. required; validate - use cmds vs. Code -- unless performance problem -- cmds require no maintenance, are more understandable, are usually documented, are well-tested - use stdin,stdout,stderr -- allows chaining/piping/composing commands -- cleaner output
mkdir c:\temp
cd /d c:\temp
echo hi
set greeting=hi
echo %greeting%
if not exist c:\temp\uwnetid mkdir c:\temp\uwnetid
echo 1 hi >C:\temp\uwnetid\greeting
type C:\temp\uwnetid\greeting
echo 2 bye >>C:\temp\uwnetid\greeting
type C:\temp\uwnetid\greeting
more <C:\temp\uwnetid\greeting
type C:\temp\uwnetid\greeting | findstr bye
for /l %n in (1,1,5) do @echo %n >c:\temp\uwnetid\test.%n
It will dump the contents of all of the files provided in the argument list.
notepad doforfiles.cmd
@echo off
set filename=C:\temp\uwnetid\files
dir /b %1 >%filename%
for /f %%l in (%filename%) do @type %%l
@echo off prevents tracing, making the output a lot more
readable.
doforfiles C:\temp\uwnetid\test.*
type C:\temp\uwnetid\files
We don't need that file, so it should be deleted afterwards.
notepad doforfiles.cmd
for /f %%l in (%filename%) do @(echo %%l & type %%l)
Here the body of the for loop does two commands,
within parentheses to group them and separated by the ampersand sign
"&",
with the tracing
of the command execution suppressed (the at sign "@").
del /f /q %filename%
Delete the file without asking for permission "/f"
and without outputting any message "/q".
doforfiles C:\temp\uwnetid\test.*
Use, for example:
call nextscript.cmd
If you don't use call, but instead simply type the script name,
it will transfer control to the other script,
never returning to the calling script.
Add 20 new users and make a new home directory for each
notepad C:\temp\uwnetid\new_users.txt
testuser1
testuser2
testuser3
testuser5
testuser6
testuser7
testuser8
testuser9
testuser10
testuser11
testuser12
testuser13
testuser14
testuser15
testuser16
testuser17
testuser18
testuser19
testuser20
Note that since the user names are so consistent, there is an
easier method. But in the real world, a file of user names is very
handy, as the names will vary considerably.
notepad create_users.cmd
for /f %%l in (%1) do @net user %%l std3926pw /add
REM Create their home directories, making sure other users are denied
REM any permissions and that this user is granted change permission.
mkdir C:\home
for /f %%l in (%1) do @(mkdir C:\home\%%l & cacls c:\home\%%l /e /r Users /g %%l:C)
They will all receive the same password... not generally a good idea.
I thought you might be able to get a random number with this instead of the
std3926pw password above:
std%RANDOM%pw
but it did not work -- gave the same random number -- so it must be an overly
simplistic random number generator. To fix this using Windows batch files
is beyond the scope of this workshop.
create_users C:\temp\uwnetid\new_users.txt
rem get to the directory
cd /d C:\temp\uwnetid
rem verify contents before
for /f "usebackq" %l in (`dir /b test.?`) do @type %l
rem do the command
C:\perl\bin\perl -i.bak -p -e "s/1|3/BBB/;" test.1 test.2 test.3 test.4 test.5
rem to verify:
for /f "usebackq" %l in (`dir /b test.?`) do @type %l
That will take some explaining, both for the verification and the
Perl steps:
The /f option allows some additional options expressed in quotes. The usebackq option means to allow back-quote or back-tick characters around another command to indicate to execute it, and return the results at that spot. Here, the dir /b test.? command is being executed, and it is supposed to list all files that have the filename of "test." followed by exactly one character. That should list test.1, test.2, etc. -- but we don't want them listed to the console. Instead, we want to use the output as input to the for command, much like a pipe. Each iteration of the loop reads another line of output from the dir command, and with that line (which is the file name), we ask to type out the contents of the files.
This is called an in-place edit of multiple files. What we do is:
s/1|3/BBB/;
says to search the current line
for a 1 or a 3, and if found, replace it with the string BBB.
So what you can see is that even a simple line of Perl code can do a lot of work.
$extension = ".bak";
LINE: while (<>) {
if ($ARGV ne $oldargv) {
if ($extension !~ /\*/) {
$backup = $ARGV . $extension;
}
else {
($backup = $extension) =~ s/\*/$ARGV/g;
}
rename($ARGV, $backup);
open(ARGVOUT, ">$ARGV");
select(ARGVOUT);
$oldargv = $ARGV;
}
s/1|3/BBB/;
} continue {
print; # this prints to original filename
}
select(STDOUT);
I won't try to explain all of that. It is meant to illustrate that
in this case, Perl can be written concisely.
Detect removable volumes (based on code by former UWT student Peter Paquette):
use Win32::AdminMisc;
my @drives = Win32::AdminMisc::GetDrives();
my @userMedia;
#------------------------------------------------------------------------------
# For each drive on the system test to see if REMOVABLE or CDROM drives have
# media present. This can be determined by checking to see if they have a
# volume number. However, this check will fail if the media has not been
# formatted (e.g. a blank CD-R).
#------------------------------------------------------------------------------
$sent_header = 0;
foreach my $drive (@drives)
{
my $type = Win32::AdminMisc::GetDriveType($drive);
(my $volume) = Win32::AdminMisc::GetVolumeInfo($drive);
if(($type == DRIVE_REMOVABLE || $type == DRIVE_CDROM) && $volume eq "Volume")
{
if (! $sent_header)
{
print "\nYou have these devices attached to the computer:\n";
$sent_header = 1;
}
#---------------------------------------------------------------------------
# For each drive: get its type and if it is REMOVEABLE or a CDROM print it
# get its type
#---------------------------------------------------------------------------
my $type = Win32::AdminMisc::GetDriveType($drive);
print "$drive ";
$vol_type = "unknown";
if($type == DRIVE_REMOVABLE)
{
if($drive eq "A:\\")
{
$vol_type = "floppy disk";
}
else
{
$vol_type = "removeable media";
}
}
if($type == DRIVE_CDROM)
{
$vol_type = "optical (CD\\DVD) media";
}
print "$vol_type\n";
}
}
This uses the AdminMisc Perl module from Roth.net, which
provides access to various Windows APIs, allowing Perl
scripts to call Windows functions.
C:\perl\bin\perl find_devices.pl
Many useful command-line tools are only available from these kits, which in the past were parts of Microsoft books you could buy, but more recently are also downloadable from Microsoft.
These are utility tools written by some Windows programming experts and consultants -- very good quality and very powerful. They are not all commands, and some are not scriptable, so they aren't all aids to automating tasks.
One of the better scripting tools out there is AutoIT, because it allows scripting of window and keyboard events. Here is a brief example, where we will change the workgroup name:
; Open the System Properties window
Send( "#{PAUSE}" )
Sleep(500) ; Give it a little time to pop up completely
$rc = WinWaitActive( "System Properties", "", 60 )
if $rc == 0 then error( "Timeout Error: waiting for 'System Properties'" )
WinActivate("System Properties") ; Make sure it is the active window
Sleep(200) ; Give it a little time to pop up completely
Send( "{RIGHT}" )
Sleep(200) ; Give it a little time to pop up completely
; Click the 'Properties...' or 'Change...' button
Send( "!c" )
$MenuTitle = "Computer Name Changes";
$rc = WinWaitActive( $MenuTitle, "", 5 )
if $rc == 0 then error( "Timeout Error: opening 'Network Identification' --> '" & $MenuTitle & "'")
WinActivate($MenuTitle) ; Make sure it is the active window
; Go to the workgroup field
Send ( "!W{TAB}" );
Sleep(200) ; Give it a little time to move
; Provide a new workgroup name
Send ("MYGROUP")
Here you see a lot of keyboard events and waiting for windows to
appear:
If you don't know about hotkeys, it can be difficult to open some of the windows.
C:\temp\uwnetid\change_workgroup.au3
C:\temp\uwnetid\change_workgroup.exe
c:\temp\uwnetid\change_workgroup
Use the GUI, or the command schtasks. We use the latter since it is easier to explain.
Whenever you want something to be done periodically, from every minute to every day, week, month, at startup or shutdown, or other time, you need to schedule a task to do it. Common tasks are backups (but the ntbackup wizard provides its own scheduling), time synchronization, cleanups of temporary directories, and restarts.
schtasks
schtasks /?
schtasks /create /sc minute /mo 1 /tn Nagger /tr "cmd /c start """nag""" """cmd /k type C:\temp\uwnetid\test.1""""
schtasks /delete /tn Nagger
All schtasks subcommands can be executed on a remote system where you know the computer name, privileged user name and password.
Tasks are stored in C:\windows\tasks as .job files, which can be copied to other computers (user names and passwords might need to be changed).
schtasks /create /sc daily /st 01:00:00 /tn "Clean Test Backups" /tr "cmd /c del c:\temp\uwnetid\test.*.bak"
rem verify that files exist now
dir c:\temp\uwnetid\test.*.bak
rem trust that it will run at 1:00 am, but test the command now
schtasks /run /tn "Clean Test Backups"
rem Verify that they are gone
dir c:\temp\uwnetid\test.*.bak
If you don't include
@ECHO OFF
as the first line, batch processing will automatically trace the execution.
You can invoke Perl with the -d option; e.g.:
perl -d find_devices.pl
to invoke the debugger.
Ctrl-Alt-F4
to get a login prompt.
echo hi
export greeting=hi
echo $greeting
if [ ! -e /tmp/uwnetid ]; then mkdir /tmp/uwnetid; fi
echo 1 hi >/tmp/uwnetid/greeting
cat /tmp/uwnetid/greeting
echo 2 bye >>/tmp/uwnetid/greeting
cat /tmp/uwnetid/greeting
more
cat /tmp/uwnetid/greeting | grep bye
for (( i=1 ; i <= 5 ; i++ )) ; do echo $i >/tmp/uwnetid/test.$i; done
It will dump the contents of all of the files provided in the argument list.
vi doforfiles
A
#!/bin/bash
export filename=/tmp/uwnetid/files
ls -1 $1 >$filename
for file in `cat $filename` ; do cat $file ; done
:wq
bash doforfiles "/tmp/uwnetid/test.*"
cat /tmp/uwnetid/files
We don't need that file, so it should be deleted afterwards.
vi doforfiles
for file in `cat $filename` ; do (echo $file & cat $file) ; done
Here the body of the for loop does two commands,
within parentheses to group them and separated by the ampersand sign
"&".
rm -f $filename
Delete the file without asking for permission "-f".
bash doforfiles "/tmp/uwnetid/test.*"
chmod +x doforfiles
and run it as:
doforfiles "/tmp/uwnetid/test.*"
for file in `ls -1 /tmp/uwnetid/test.*` ; do cat $file ; done
Let's backup the /home/itadmin directory early in the morning of every day using the tar command.
tar -cvpzf /tmp/uwnetid_backup.tar /home/itadmin
tar is the tape archive command, and it used to be almost
exclusively used to make archives of files onto tapes. Nowadays,
it is probably used more often to create archives on disk.
tar -tvf /tmp/uwnetid_backup.tar
vi run_backup
A
#!/bin/sh
/bin/tar -cvpzf /tmp/uwnetid_backup.tar /home/itadmin
:wq
chmod u+x run_backup
./run_backup
There are two ways to do it -- automatically or manually
mv run_backup /etc/cron.daily
export EDITOR=/usr/bin/vim
crontab -e
crontab needs an editor to use; setting the EDITOR environment
variable allows crontab to use that one. Now you are in vi.
A
0 4 * * * /home/itadmin/run_backup
:wq
There can be many other similarities in automating tasks between Windows and Linux, but one can also emphasize the differences. Here are just a few minor pointers: