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\filesWe 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.cmdIf 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 testuser20Note 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%pwbut 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 %lThat 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 OFFas the first line, batch processing will automatically trace the execution.
You can invoke Perl with the -d option; e.g.:
perl -d find_devices.plto invoke the debugger.
Ctrl-Alt-F4to 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/filesWe don't need that file, so it should be deleted afterwards.
vi doforfiles
for file in `cat $filename` ; do (echo $file & cat $file) ; doneHere the body of the for loop does two commands, within parentheses to group them and separated by the ampersand sign "&".
rm -f $filenameDelete the file without asking for permission "-f".
bash doforfiles "/tmp/uwnetid/test.*"
chmod +x doforfilesand 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/itadmintar 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 -ecrontab 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: