Window NT Shell Scripting PDF
Window NT Shell Scripting PDF
Shell Scripting
Tim Hill
MACMILLAN
TECHNICAL
PUBLISHING
U•S•A
I
Windows NT Shell Scripting Acquisitions Editor
Jane Brownlow
By Tim Hill
Development Editor
Published by: Lisa M. Gebken
Macmillan Technical Publishing
Project Editor
201 West 103rd Street Brad Herriman
Indianapolis, IN 46290 USA
Copy Editor
All rights reserved. No part of this book may be reproduced or Susan Hobbs
transmitted in any form or by any means, electronic or mechani Market Reviewers
cal, including photocopying, recording, or by any information Ryan Maley
storage and retrieval system, without written permission from Robert Marsh
the publisher, except for the inclusion of brief quotations in a Technical Editor
review. Louise Hudgins
Team Coordinator
Copyright © 1998 by Macmillan Technical Publishing
Amy Lewis
Printed in the United States of America 6 7 8 9 0 Book Designer
Gary Adair
ISBN: 1-57870-047-7
Cover Designer
Library of Congress Cataloging-in-Publication Data: 97-80990 Aren Howell
Production Team
Warning and Disclaimer Argosy
Trademark Acknowledgments
All terms mentioned in this book that are known to be trademarks or service
marks have been appropriately capitalized. Macmillan Technical Publishing
cannot attest to the accuracy of this information. Use of a term in this book
should not be regarded as affecting the validity of any trademark or service
mark.
Windows NT is a registered trademark of the Microsoft Corporation.
About our technical reviewers . . .
These reviewers contributed their considerable practical, hands-on expertise to
the entire development process for Wmdows NT Shell Scripting. As the book
was being written, these folks reviewed all of the material for technical
content, organization, and flow. Their feedback was critical to ensuring that
Windows NT Shell Scripting fits our readers' need for the highest quality
technical information.
Louise Hudgins is a network telecommunications analyst and LAN administra
tor at Thomas Nelson Community College in Hampton, Virginia. She is a
Microsoft Certified Systems Engineer (MCSE) and Microsoft Certified Trainer
(MCT) for Windows NT 3.51 and 4.0, and is currently working towards a
degree in computer science. Louise believes that the best place to shop around
is in the marketplace of ideas.
Bob Marsh has been a Windows NT user and administrator since NT 3 . 1 beta
in 1 993. He is a co-founder and vice president of engineering at Document
Technologies, Inc. in Sunnyvale, California. He is the holder of three U.S.
patents and is co-inventor of one of the first personal computers, the Processor
Tech Sol-20, which debuted in 1 976. This machine is now on display in the
Smithsonian's Museum of American History in Washington D.C. Bob is also
one of the co-founders of the Homebrew Computer Club in Menlo Park and
has been featured in two books on the history of personal computing: Fire in
the Valley and Hackers. He is an alumnus of the University of California,
Berkeley (class of 1 970) and is a lifelong resident of Berkeley.
Dedication
To Donna.
Acknowledgments
My appreciation and thanks go to the editorial and production teams at
Macmillan Technical Publishing for their help and encouragement throughout
this project. In particular, I would like to thank Linda Engelman for letting me
write this book, and Jane Brownlow and Lisa Gebken for all their help and
(above all) patience as I juggled writing and a full-time career.
I would also like to thank my colleague Bob Marsh for all his efforts in uncov
ering technical errors in the manuscript. As usual, Bob was unwavering in his
attempts to find as many mistakes as possible in my work.
Finally, thanks go to my two children, Alex and Becky, for putting up with dad
disappearing to "play on the computer" instead of with them.
I
Contents at a Glance
Introduction 1
Introducing Scripts . . . . . . . .
. .. ... . .. . . . . .. .
.. . ...... . . . .... . . . . . . . . . . 14
... ....... . .. . .. . . .. ... ...
Script Arguments . . . . . . . .. .. .. . . . . . . . . . . . . . . . . . . . . . . . . . 15
.. ..... . .. . ... . .... .. . . .. .... ..
The PATH Command and PATHEXT Variable . . . . ... . . . . . . . . . 38 ... . . ... ..... .
Integrating New Script Languages with the Shell . . . . . . . . ..44 . . . .... ....
REM ••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••• 49
CLS ••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••• 49
COLOR ••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••• 49
TITLE ••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••• 50
@ •••••.••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••• 50
ECHO 51
•••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
MORE ••••••••••••••••••••••••••••••••••.•••••••••••••••••••••••••••••••••••••••••••••••••••••• 60
SORT •••••••••.••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••• 60
FIND ••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••• 60
CLIP [RK] ................................................................................61
The Windows NT Command Scheduler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .61
3 Script Parameters and Variables 65
Variable Basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
Environment Variable Sources ... . ...... ... .... .. ... . . . ... ..66 . . . . . .. . .... ... ....
Returning Procedure Values .......... ... .... ...... ..... ...... . .. . .75 . . . .. . ... . . ...
Using SETLOCAL and ENDLOCAL . .... .... . ... . . . .. ..... ...... . . 78 . .. . .. .. ... ... .. . .
Variable Tunneling .... ..... ... .... .. ....... . . .. ... .... . . .. . . . . . ...79
.. . ..... ..... . . . .. .
Special Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
Advanced SET Commands .. ..... . ...... . .. .... .. ....... .. .. ...... ... .82.. .. . . . . . ... . .. .... ..
String Indexing ....... ... ..... . . ... .... .. . .... . ... . . .. .. . .. .... .. . ...... ....90
. ... ...... .
Using Double Quotes... ... . ...... . .. .. .. .... . ... .. ........ 97 .... . . .... . .. ... .. .. . .. ..
FC ........................................................................................... 283
FIND . .. . . . . . . 284
... ............. ................................... ................ . ..... . ...
.
I NSTSRV [ RK ] . .. . . . .
......... ... .. .... .. . . . . 295
... .......... . ... ....... ... ....... .......
K I L L [ RK ] ••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••295
Labels .................................................................................... 296
LOCAL [ R K ] ••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••296
LOGEVENT [ R K ] 297
•••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
LOGOF F [ R K ] 298
••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
MD ••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••• 298
MKD I R , MD ••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••298
MORE ••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••• 298
MOVE ••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••• 300
NET ACCOUNTS 300
••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
NET F I L E ••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••304
N ET GROU P , N ET LOCALGROUP ................................................. 305
NET LOCALGROUP ..................................................................... 306
N ET NAME ................................................................ . . . ............. 306
N ET PAUSE . . . . . . . . .307
......... ........................ .......... ........ . .... . .. ..... ....
.
N ET USE . .. . . . . . . .
. .... . .. ... . .. .. .. . . .
..... . . .. ..
... . . ....... ............. ... 311
...........
PATH 318
.......................................................................................
PAUSE 319
.....................................................................................
PERMCOPY [ RK ] 319
•••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
POPD 319
.......................................................................................
PROMPT 319
...................................................................................
PULI ST [ RK ] 321
..........................................................................
PUSHD 321
.....................................................................................
RD........................................................................................... 322
REG [ R K ] 322
................................................................................
REM 324
•••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
RENAME 325
•••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
REPLACE 325
..................................................................................
RMD I R , RD 326
..............................................................................
RMTSHARE [ R K ] 326
.......................................................................
ROBOCOPY [ R K ] 327
.......................................................................
SC [ RK ] 331
.................................................................................
SCL I ST [ RK ] 334
..........................................................................
SCOPY [ R K ] 334
............................................................................
SET 335
.........................................................................................
SETLOCAL 337
................................................................................
SHI FT 338
.....................................................................................
SHUTDOWN [ R K ] 339
.......................................................................
SLEEP [ R K ] 340
............................................................................
SOON [ R K ] 340
..............................................................................
SORT 341
•••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
START 344
•••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
SUBST 346
.....................................................................................
TIME 347
.......................................................................................
T IMEOUT [ RK ] 347
........................................................................
TITLE .....................................................................................348
TRANSLATE [ RK] 348
.....................................................................
TYPE .......................................................................................348
USRSTAT [ RK ] 349
........................................................................
WHOAM I [ RK ] ..........................................................................350
WI NAT .....................................................................................351
XCACLS 351
...................................................................................
XCOPY .....................................................................................351
xvi Windows NT Shell Scripting
Today, GUI ( Graphical User Interface) applications and tools dominate the
Windows world, including Windows NT. Buttons, mouse devices, and icons
make computers more accessible than was ever dreamed when the only inter
face to a computer was an ASCII terminal.
So why a book about Windows NT shell scripting? Aren't scripts just MS-DOS
batch files with a fancy name? And everyone knows Microsoft hasn't changed
batch files for years!
Well, batch files have changed. With the release of Windows NT 4.0, the com
mand shell has been given enough new features to fill a book . . . this book, in
fact. Did you know you could do arithmetic with environment variables ? Or
walk a complete directory tree with a FOR command? If you're an NT power
user, administer NT systems and servers, or use logon scripts, then these and
other new script language features enable you to automate many mundane or
difficult tasks.
With its widespread acceptance as both a server and client platform, many
other script languages have been ported to Windows NT. Many of these lan
guages, such as Perl, Awk and T cl, come from the Unix world. Others, such as
REXX, come from OS/2. Each of these languages has its own strengths and
limitations, but none are quite as suited to systems management as the native
scripting of Windows NT. Quite apart from anything else, the built-in scripting
of Windows NT is always available on every installation. This universal avail
ability makes a good knowledge of NT scripting virtually mandatory, particu
larly if you manage large NT installations.
I designed this book as a complete reference for Windows NT scripting. To do
this, I've drawn together material from many different sources: on-line help
( GUI and command line), printed documentation, the.Microsoft Knowledge
Base and web site (http://www.microsoft.com/kb), and (most importantly) my
2 Introduction
own years of working with Windows NT. Some of the most useful features of
the Windows NT scripting language have been poorly or incorrectly document
ed (if at all). Therefore, one of my goals in this book is to ensure that these
errors and omissions are corrected, allowing use of the rich scripting features
now available in Windows NT.
A word about programming: This is not a book about programming-it's
about scripting. Although scripting has many of the same trappings as pro
gramming (such as loops, control flow, and variables), it is more pragmatic,
and focused on quick solutions to small problems. In this spirit, you will find
very little in the book about structuring code, or good techniques for com
ments, or any of the other more formal aspects of writing good programs. Such
things are less important for short scripts. I do, however, assume that the read
er is familiar-in principle at least-with the basic ideas of programming, such
as subroutines and variables.
Part II provides a set of real-world scripting solutions. These solutions are pre
sented as complete, ready-to-use, scripts. Each script can be used as-is, or
modified to suit local conditions. The sample scripts can be found at
http://www.macmillantech.com.
This example shows one possible use of the AT command. It shows the AT com
mand itself, followed by a computer name prefixed with two backslash
4 Introduction
1 . at /DELETE
2 . at / delete /yes
3. at \ \ mothra /delete
Also note that the numbers in lines of code are for reference purposes only.
They are not to be included in any code commands or instructions.
Tips are given throughout the book, which provide you with useful short
cuts and other hints.
Th�\�as1cs of S��i�ts
:.'·2r Tti�;i·'wind�ws.N'JE·•Co1llinand Sh.ell
.3 Scr:ii>.t.Pa:r�iueters .and Variables
• What is a script?
Here, we introduce scripts and provide some history about the origins of
the Windows NT script language. A very simple script is shown, to illus
trate the mechanics of script development.
• The Console Window
Since scripts are console applications, a good knowledge of the Windows
NT console window is important. This section provides a full description
of the console window, and shows how it can be customized.
• Introducing Scripts
This section provides additional information on how scripts are con
structed and executed.
• Script Arguments
Like other command-line commands, scripts can accept arguments. Here,
we introduce the basic syntax for accessing command-line arguments
from within a script.
• Special Script Lines
To make a script user-friendly, it's advisable to start each script with a
standard preamble. This section shows a standard preamble that can be
used with any script.
What Is a Script?
This is a book about Windows NT scripting. In Windows NT, a script is a
record, in a text file, of a sequence of shell commands. (A shell command is
approximately the same as a command typed into a command prompt
window. ) Once created, a script can be executed as if it were an executable
program; for example, by double-clicking a script file from Windows Explorer,
or by typing the name of the script in a command prompt window.
8 Part I: The Script Language
The ECHO command simply echoes its arguments by displaying them in the com
mand prompt window. In Windows NT scripting, each command is placed on
its own line, and any arguments for that command follow the command name
on the same line. Generally, individual arguments are separated by spaces, but
the ECHO command treats everything that follows on the line (spaces included)
as text to be echoed.
The easiest way to create this simple script is to use Windows Notepad editor.
Start Notepad and type the ECHO line as previously shown. Press Enter at the
end of the line (all script lines should end with a new line, even the last). Save
the file in a convenient directory, giving it the name HELLO.BAT.
Now start a Windows NT command prompt. Switch to the directory in which
you saved the file HELLO.BAT, type HELLO, and press Enter. The ECHO com
mand is displayed following a command prompt, and then the output of the
ECHO command appears on the next line:
1 . C : \ sc ripts>hello
2 . C : \ sc ripts>echo Hello , worldl
3 . Hello , worldl
If the HELLO script does not work as expected, check that you are in
the correct directory. The command shell will give the following error if it
cannot locate a command.
The name specif ied is not recognized as an internal or exte rnal command ,
ope rable program or batch file
can also press Alt+Enter to switch to or from full screen mode. The Command
History options control the buffers used for the command history feature.
Command history is described in Chapter 2, "The Windows NT Command
Shell. "
Quick Edit mode uses the mouse for cut and paste operations. When Quick
Edit is unchecked, the System menu Mark command enters cut and paste
mode. In this mode, the mouse is used to select a block of text to copy to the
clipboard. The System menu Copy command then places this text in the clip
board. When Quick Edit is checked, the Mark command is not required. Text
can be directly selected with the mouse by dragging. Quick Edit mode is not
compatible with applications that use the mouse.
Insert mode sets the default line edit mode to insert, rather than overwrite.
This mode can also be changed using the DOSKEY command. When editing a
command, the mode can also be toggled using the Insert key.
Window Size options set the width and height of the console window in char
acter units. The window size is the physical size of the console window.
Typically, both Screen Buffer Size and Window Size are set to the same values.
Scroll bars will appear if the Window Size is smaller than the Screen Buffer
Size.
Using a screen buffer which is larger than a window buffer allows command
output to be reviewed even if it has scrolled off the top of the console window.
In many cases, using a longer screen buffer avoids the need to use the MORE
command to paginate command output.
The Window Position options set the position of the console window.
Typically, the Let System Position Window option is checked, giving Windows
NT control of the initial window position. Uncheck this option and enter the
window position (in pixels) to set a fixed initial window position.
Screen text and background colors can also be set using the COLOR command
(see Chapter 2) or the /T switch of the CMD command.
If you are working with a high-resolution display it is useful to set up a "Big
Command Prompt" shortcut and place it on your desktop. This is most easily
done as follows:
1 . Right-dick on the Start button and select the Open option. In the Start
Menu window, double-dick on the Programs item.
2. Hold down the Ctrl key and drag the Command Prompt item from the
Programs window onto the desktop. Close the Programs and Start Menu
windows.
14 Part I: The Script Language
3. Right-dick the new Command Prompt icon on the desktop and select the
Properties command.
4. Change the Layout and Font options to suit your taste. Try setting both
Screen Buffer and Window Size to 43 lines, then adjust the font size to
provide a suitable fit.
5. Run the new Command Prompt by double clicking the icon.
Introducing Scripts
As previously described, a Windows NT script is a text file containing one or
more shell commands to execute. Shell commands are interpreted by the
Windows NT command shell, CMD.EXE, which is the subject of Chapter 2.
The shell can execute commands typed at the keyboard or read from a script
file. With one or two exceptions, any command that can be entered at the key
board can also be used in a script, and vice versa. Some commands only make
sense when used interactively, while others (such as the GOTO command) have
no meaning outside a script file.
Script files have a file type of .BAT or .CMD. The .BAT type was inherited
from MS-DOS, while the .CMD type came from OS/2. However, the command
shell treats both file types identically. The .BAT file type is used in this book,
but .CMD can be used if preferred. Once a script file is created, you can exe
cute it simply by typing its name (with or without the file type) as a shell com
mand. For example, to execute the script HELLO.BAT, type HELLO or
HELLO.BAT at the command prompt and press Enter:
1 . C : \ >hello
2. C : \ >echo Hello , wo rld !
3. Hello , wo rld !
4. C : \>hello . bat
5. C : \ >echo Hello , world !
6. Hello , world !
If the script name includes a directory path (and optional drive letter), the shell
looks for the script in the specified directory. If the script does not include a
directory path, the shell looks for the script file in the current directory. If the
script is not found in the current directory, the shell then searches the list of
directories specified by the current search path. The search path is specified
using the PATH command (described in Chapter 2) or by altering the PATH envi
ronment variable via the System icon in Control Panel. Figure 1 . 6 shows the
PATH variable in the Control Panel.
Chapter 1: The Basics of Scripts 15
Figure 1 .6. Altering the PATH environment variable i n the Control Panel
One useful convention is to create a directory for all scripts (for example,
C:\SCRIPTS) and then add this directory to the system path. All scripts
placed in this directory are then available for execution from any com
mand shell.
Once the shell locates the script file, it begins reading, interpreting, and execut
ing the commands in the file. Each command typically occupies one line, and
the commands are read and executed in the order they are listed in the file. By
default, the command shell echoes each command before executing it. Script
execution ends when the end of the script file is reached-there is no explicit
END or STOP command.
Script Arguments
Arguments can be passed to a script from the command line. Script arguments
are entered on the command line, separated from the script file name and each
other by spaces. The following shell command executes the script
SCRIPTl .BAT (or .CMD) and passes it three arguments: c : , E : \ and / P.
C : \>script 1 c : e : \ / p
16 Part I: The Script Language
Within the script file, script arguments are referred to as %1 for the first argu
ment, %2 for the second argument, and up to %9 for the ninth argument. These
argument references are called parameters, or more correctly, formal parame
ters. The replacement of parameters with actual arguments is called parameter
substitution. Arguments and parameters are described in detail in Chapter 3,
"Script Parameters and Variables."
Parameter substitution can be understood most easily with an example. Use
Notepad to create a one line script called ARGECHO.BAT, containing:
echo You entered : [%1 ] [ %2 ] [ %3 ] [ %4 ]
Now execute the script, and enter any desired arguments. For example:
1 . C : \>argecho one alex becky
2 . C : \ >echo You entered : [ on e ] [ alex ] [ becky ] [ )
3 . You entered : [ on e I [ al e x ] [ b e c k y ] [ I
The ECHO command is first echoed, and then executed. Notice that the parame
ters have already been replaced by the actual arguments before the command is
echoed. Also notice that the %4 parameter is replaced by nothing, since in this
example, only three arguments were entered.
Experiment with different arguments by modifying ARGECHO.BAT to include
additional spaces or tabs between arguments. Try placing an argument in dou
ble guotes. Finally, modify ARGECHO to echo %0 in addition to the other parame
ters '. These and other properties of script parameters are discussed fully in
Chapter 3.
These "magic" script lines perform some basic housekeeping. The individual
commands used are described in detail in Chapters 2, 3, and 4. In outline,
however, these commands operate as follows:
• Prefixing a command with an @ character stops the command shell from
echoing the line when it is executed, resulting in a less cluttered display.
Chapter 1: The Basics of Scripts 17
• The ECHO O F F command {line 1 ) turns off command echo for the script.
This stops all commands from being echoed by the shell, thus reducing
clutter when the script runs, as only the output of commands is dis
played.
• The first IF command {line 2) is used as a debug aid. It can be interpreted
as follows: If a variable named ECHO exists, execute an ECHO command
using the contents of the variable ECHO as the only argument. If no ECHO
variable exists, this line does nothing. If, however, the variable does exist,
the ECHO command is executed. If the variable ECHO contains the text ON,
then the ECHO command that is executed will be:
echo ON
This SET command defines a variable called ECHO with a value of ON. The
ability to quickly switch command echo on or off for all scripts is very
useful when debugging a script.
• The second IF command {line 3 ) checks that the script is executing on
Windows NT. If the script is running on Windows NT, the IF command
will do nothing, and execution will continue at the next line. If, however,
the script is executing on MS-DOS or Windows 95, the GOTO EXIT com
mand will execute. This causes the shell to jump ahead to the last line of
the script and immediately stop script execution.
• Line 7, containing : EXIT, is the target label for the GOTO statement in line
3. It should be the last line in the script.
The use of a variable named ECHO within an ECHO command might appear
confusing. This is one place where the use of uppercase for variables and
lowercase for command names helps improve readability by clearly dis
tinguishing between the ECHO variable and the ECHO command.
In Windows NT, there are actually more elegant methods to achieve the effect
of this script outline, but these methods are not backward compatible. The
outline shown has the virtue of being compatible with MS-DOS version 3.x
onwards and all versions of OS/2.
Chapter 2
The Windows NT
Command Shell
the specified script file. Figure 2.2 shows the command execution sequence
while the shell is in script mode. Execution of the script ends when the shell
reaches the end of the script file. At this point, the shell returns to interactive
mode, displays another command prompt, and waits for keyboard input.
Execute
Command
NO
( End
Display
Prompt
Execute
Command
End
)
This example changes the command prompt to three question marks. Notice
that the shell uses this prompt on line 2 in the example. To revert to the default
prompt, enter a PROMPT command without any prompt text. For example:
1 . ???p rompt
2 . C: \ >
1 . C : \>prompt $T$G
2 . 1 4 : 23 : 50 . 35>
Using $G to represent the > character might seem unnecessary, as this character
can simply be typed. However, this does not work, because the command shell
reserves certain characters for special purposes. These reserved shell characters all
have $c equivalents, so that they can be used in command prompts. For example,
$A is used for an ampersand, $L for a < character, and so on. Table 2.1 shows the
complete set of special characters recognized in a command shell prompt.
Chapter 2: The Windows NT Command Shell 23
The $+ special character works in conjunction with the PUSHD and POPD com
mands (see Part III). These commands manage a push-down stack of directo
ries and drives, and the $+ special character displays a sequence of + characters
in the command prompt, one for each level in the push-down stack.
If the current drive is a network drive, the $M special character displays the
remote UNC name of this drive in the form \\server\share. If the current drive
is a local drive, then $M does not display anything.
The current prompt text is stored in the PROMPT environment variable. Changing
the prompt changes the value of this variable and vice versa. Thus, these two
commands have the same effect:
1 . C : \ >prompt [ $p ]
2 . C : \ >set PROMPT= [ $p ]
24 Part I: The Script Language
Command Name
A.
C:\>copy c:\* .bak e:\backup /s
,
y
Prompt
' Arguments
In Figure 2.3, the command name describes the action to be performed, while
the arguments provide additional information needed to carry out this action.
The syntax of the command arguments is specific to each command. However,
there are a number of well-established conventions for command argument
syntax. These are only conventions, however, and each individual command is
free to interpret the supplied arguments however it chooses:
• First, multiple arguments are normally separated from one another by
spaces. In Figure 2.3, the command has three arguments, c : \ * . bak,
e : \ ba c k u p, and I s. Occasionally, other characters are used as argument
separators. For example, the COPY command can use + characters to sepa
rate multiple filenames.
• Second, any argument that contains spaces or begins or ends with spaces
must be enclosed in double quotes. This is particularly important when
using long file and directory names, which frequently contain one or
more spaces. If a double-quoted argument itself contains a double quote
character, the double quote must be doubled. For example, enter " Quoted "
Argument as " " " Quoted " " Argument " .
example will not work as expected, because < and > are reserved shell
characters:
1 . C : \ >echo <dir>
2 . The syntax of the command is incorrect .
Typically, the reserved shell characters are not used in commands, so col
lisions that require the use of escapes are rare. They do occur, however.
For example, the popular PKZIP program supports a - & switch to enable
disk spanning. To use this switch correctly under Windows NT, - A& must
be typed.
The I F command compares the letter "a" to the letter "A" and echoes MATCH if
they compare. The I I switch compares the two letters without regard to letter
case. Therefore, not surprisingly, the command echoes MATCH.
Here is the same IF command entered into an MS-DOS 1 6-bit
COMMAND.COM shell (running on Windows NT on the same computer) :
1 . C : \>if / i a==A echo MATCH
2 . MATCH
._....
....... ...
N!VDM.E>CE
llPCSS.E>CE
-
TAPISRV.E>CE
NDDEAllNT.El<E
DID.El<E
AASMAN.E>CE
ElG'l.DAEA.E>CE
PSTDAES.E>CE
....,,....
nphaok. ...
l..OADWCEXE
AEMINDEA.E>CE
�
-
!'SP.EXE
TASKMGR.E>CE
Like most other commands, the command shell CMD.EXE accepts several
switches that control various shell options. Table 2.2 shows these switches,
which are described in detail in the " Command Reference" in Part III.
Table 2.2. CMD.EXE Switches
Switch Description
IX Enables command extensions (default).
IY Disables command extensions.
IA Command output to files or pipes will be ANSI (default).
IU Command output to files or pipes will be Unicode.
IT Sets foreground and background window colors.
IC Executes command specified and then terminate shell.
IK Executes command specified and then prompts for additional commands.
To specify shell switches, place them after the CMD command on the command
line. It is not possible to directly enter shell switches if the shell is started from
the Start menu Command Prompt command, or by double-clicking a .BAT or
.CMD script file (the first and last methods in the preceding list).
Without any switches, a command shell starts in Interactive mode with com
mand extensions enabled. Command extensions are certain features added to
the command shell since Windows NT was first released. In general, these
extensions are backward compatible, but they can occasionally cause older
Windows NT and MS-DOS scripts to fail. In this case, the /Y switch disables
the extensions and, in effect, runs an MS-DOS compatible command shell.
The /C and / K switches directly execute a command. The command to execute
is specified following the switch. For example:
1 . C : \ >cmd /c echo Run this . . .
2 . Run this . . .
All command line arguments following the / C or / K switch describe the com
mand to execute. The /C switch executes the specified command, and the com
mand shell then terminates. The / K switch executes the specified command, and
the shell then enters Interactive mode. The I K switch is particularly useful to set
up a command shell to a predetermined state before the first command prompt
is displayed.
The /C and I K switches both accept any valid shell command, including the
name of a script file to execute. In this case, the shell enters script mode and
executes the specified script. This is the method the Windows NT Explorer
uses to start a script file when it is opened. For example, if you double-dick on
the file SCRIPT.BAT, Explorer actually executes this command:
cmd /c script . bat
Chapter 2: The Windows NT Command Shell 29
The EXIT command can also be used in script mode. The command should be
used with care, however, as the shell terminates immediately, effectively abort
ing script execution. Scripts should normally end by executing to the end of the
script file, or by the GOTO : EOF command (see Chapter 4 ) .
I f a script file i s running i n a shell that was started using the / C switch, the
command shell terminates when the script reaches the end of the file.
The first PROMPT command changes the prompt. A new command shell is then
invoked with the /Y switch (to disable command extensions}. Notice that the
new command shell inherits the prompt from the previous shell. The second
PROMPT command returns the prompt to the default, as can be seen in the subse
quent shell prompt (c : \>}. The EXIT command exits the nested command shell,
reverting to the previous (original} shell. Notice that the prompt reverts to the
modified form, showing that the second command shell has indeed terminated.
30 Part I: The Script Language
key t o delete the entire command, and press Enter to execute the command.
The cursor does not have to be at the end of the line when Enter is pressed.
By default, the character editor operates in Overwrite mode. New characters
typed overwrite characters at the current cursor location. Pressing the Insert
key switches to Insert mode. In Insert mode, characters to the right of the cur
sor are shifted to the right as new characters are entered at the cursor location.
Repeatedly pressing Insert toggles back and forth between the two modes. The
cursor changes shape to indicate the mode-Insert mode is indicated by a larg
er, block shaped cursor. The mode resets when the Enter key is pressed.
The default Insert/Overwrite mode can be changed from Overwrite to Insert
either by the DOSKEY command or via the Console Window property sheet's
Options tab, as described in Chapter 1 .
Template Editing
The second editing method, template editing, works in conjunction with a hid
den command buffer, the template, which contains a copy of the most recently
entered command. Template editing is present for compatibility with MS-DOS,
and the newer command history editing commands generally make template
editing obsolete.
The template F4 command is useful to quickly delete blocks of characters in a
command line. Position the cursor at the first character to delete and press F4.
A popup prompt appears. Enter a single character, and all characters in the
command line from the cursor up to (but not including) the first instance of
the specified character are deleted.
Arrow and Down Arrow keys move up and down through the list of com
mands, while the Page Up or Page Down keys move to the start or end of the
command list. The Esc key closes the history buffer popup window without
executing a command.
Enter the command number, and the specified command is recalled to the com
mand line ready for editing or execution. The F9 key can also be used while
the command history buffer popup window is displayed.
Windows NT supports command history editing for any program which reads
keyboard input on a line-by-line basis. Each program maintains its own com
mand history, so multiple command shells each have an independent command
history buffer.
The default value for this is 0x0, which disables command completion. To
enable command completion, set this value to the ASCII code for the key to
use as the command completion key. The Tab key, value 0x9, is a good choice
since it is not normally used in commands. The value is located in the per-user
portion of the registry, and is therefore enabled on a per-user basis.
Once enabfed, command completion operates as follows:
1 . When entering a file or directory name, type the first few characters of
the name and press the chosen command completion key (e.g. the Tab
key).
2. The shell searches the current directory for a file or directory name which
begins with the specified characters, and replaces the typed characters
with the complete file or directory name.
3. Pressing the command completion key again cycles through all additional
matching file names.
For example, suppose the current directory (C:\BOOK) contains three files,
CHAP01 .DOC, CHAP02.DOC and CHAPTER.DOC. Type the following, but
do not press Enter:
C : \ book>type chap
Press the command completion key. The command line immediately changes
to:
C : \ book>type " c : \boo k\chap01 . doc "
The partial file name is replaced with the first file name found in the directory.
The full path name is substituted, and the whole argument is placed in double
quotes. This ensures that a valid argument is created even if the file name
34 Part I: The Script Language
contains spaces. Press the command completion key again, and the command
line changes to:
C : \book>type " c : \book \ chap02 . doc "
This example clears the command history buffer and sets the number of com
mands in the buffer to 1 00. The command history buffer size can also be set
for a console window using the Console Window property sheet Options tab,
as described in Chapter 1 .
The final set of DOSKEY commands provides control of command shell macros.
Command macros are shorthand commands for longer, more complex shell
commands. Macros can reduce typing or, in scripts, provide simple one-line
functions. For example, to define a new macro named LS, which executes a DI R
command, enter:
C : \ >doskey ls=dir
The command shell will now accept LS as an alias for the D I R command. For
example:
1. C: \ >ls
2. Volume i n drive C i s BOOTFAT
3. Volume Serial Number is 3F3F - 1 704
4.
5. Directory o f C : \
6.
7. 05 /31 /94 01 : 22p 54 , 645 COMMAND . DOS
8. . . . etc .
Command macros, like all shell commands, are not case sensitive. The simple
definition of LS is not a direct replacement for the D I R command, however,
because it does not accept arguments. For example:
C : \>ls * . dos
will not work as expected. The * . DOS argument is ignored, and the entire direc
tory is displayed. To pass arguments to a macro, define the macro as follows:
C : \>doskey ls=dir $*
The special $* argument acts as a placeholder for all arguments entered on the
command line. The LS macro is now an exact replacement for the DIR com
mand. The DOSKEY section in the "Command Reference" in Part III lists addi
tional special arguments that can be used within macro definitions.
Obviously, directly replacing one command by an alias is of limited use.
However, macros can replace more complex commands. For example:
C : \>doskey ls=dir /od $*
This definition of the LS macro always provides directory listings sorted in date
order. The /OD switch tells the DIR command to sort files according to date and
time.
36 Part I: The Script Language
The following macro definition creates a command that displays the user name
of the currently logged-on user:
1 . C: \>doskey myname=for /f " delims=\ tokens=2 " %i in ( ' whoami ' ) do @echo %i
2 . C : \>myname
3 . TimHill
This example creates a DI RCOUNT macro that counts the number of directories in
a specified directory. The $8 argument acts as a placeholder for the pipe symbol
( : ). Alternatively, the pipe symbol can be entered directly by escaping it using a
A character. Pipes are described in the section " Command Redirection. "
Macros can b e used with any Windows NT application which accepts line-by
line command input. However, each macro is explicitly defined for a specific
application. By default, macros are defined for use by the command shell,
CMD.EXE. The / EXENAME switch defines a macro for another application. For
example, to define an EXIT macro for use with FTP, enter:
C : \ >doskey / exename=ft p . exe exit=bye
The / MACROS switch lists defined macros for the command shell, for example:
1 . C : \ >doskey /macros
2. ls=dir $*
The / EXENAME switch lists macros for a specific application, for example:
1 . C : \ >doskey /macros / exename=ftp . exe
2 . exit=bye
The / MACROS : ALL switch lists macros for all applications. The macros for each
application are listed under the application name, which is placed in brackets.
The / MACROFILE switches reads a set of macro definitions from a file, for
example:
C : \ >doskey /macrofile=macros . mac
The format of macros in the macro file exactly matches the output of the
DOSKEY command with the / MACROS : AL L switch. Therefore, it is possible to define
a set of macros interactively and then use DOSKEY to create a macro file. Later,
the macros can be recalled. For example:
Chapter 2: The Windows NT Command Shell 37
1 . C: \ >doskey ls=dir / od $*
2. C: \ >doskey / exename=ftp . exe exit=bye
3 . . . . etc .
4 . C: \ >doskey /macros : all >macros . mac
This starts a new shell and pre-loads all the macros in MACROS.MAC. If this
command is placed in a shortcut, a new command shell can be started and a
set of macros loaded automatically without any typing.
The PATH command manipulates the PATH environment variable, although the
variable can also be directly manipulated via the SET command (see Chapter 3
for a description of the SET command). To set a new system path, follow the
PATH command with a new path list. For example:
C : \>path c : \ bin ; c : \ scripts ; d : \winnt
This PATH command tells Windows NT to search the C:\BIN, C:\SCRIPTS, and
D:\WINNT directories for executable files.
Enter a PATH command without any arguments to display the current search
path. For example:
1 . C : \>path
2 . PATH= d : \winnt40 \ system32 ; d : \winnt40 ; d : \ ntreskit ; c : \bin ; c : \dos
One common use of the PATH command is adding a new directory to the search
path. To do this, specify the existing search path as part of the new path. For
example, to add a new directory, C:\NEWDIR, to the start of the path, use this
command:
C : \>path c : \ n ewdir ; %PATH%
Use this command to add the same directory to the end of the path:
C : \>path %PATH% ; c : \ newdir
The PATH variable is initialized from the following sources of information:
• The System Environment, which is set via the Control Panel System icon.
• The User Environment, which is set via the Control Panel System icon.
• Any PATH statements in AUTOEXEC.BAT (if parsing is enabled).
At logon time, path information from the sources listed above is concatenated
together to form the initial path. After logging on, the PATH command is used to
alter the path.
The PATHEXT environment variable defines the list of file extensions checked by
Windows NT when searching for an executable file. Like the PATH variable,
Chapter 2: The Windows NT Command Shell 39
semi-colons separate individual items in the PATHEXT variable. The default value
of PATHEXT is . COM ; . EXE ; . BAT ; . CMD. The PATHEXT variable is manipulated via the
SET command. For example, to add the .PL extension, use the following
command:
C : \ >set PATHEXT=%PATHEXT\ ; . pl
The following section describes how Windows NT and the command shell use
the PATH and PATHEXT variables.
the search path. If the command name does contain a path, the shell only
checks the specified directory for a matching executable file.
If the command name includes a file extension, the shell searches each directo
ry for the exact file name specified by the command name. If the command
name does not include a file extension, the shell adds the extensions listed in
the PATHEXT environment variable, one by one, and searches the directory for
that file name. Note that the shell tries all possible file extensions in a specific
directory before moving on to search the next directory (if there is one).
For example, the following command explicitly specifies the path, command
name, and file extension:
C : \ >c : \ bi n \ edit . exe
This command executes the program EDIT.EXE found in the directory C:\BIN.
If the program is not found, the shell reports an error.
This example omits the path to EDIT.EXE:
C : \ >edit . exe
To execute this command, the shell searches the current directory and then
each directory in the search path until EDIT.EXE is found, or reports an error
if the file is not found.
This example omits the path and file extension:
C : \ >edit
To execute this command, the shell searches the current directory and then
each directory in the search path. Assuming that the PATHEXT variable contains
. COM ; . EXE ; . BAT ; . CMD, each directory is searched for EDIT . COM, EDI T . EXE, EDIT . BAT
and EDI T . CMD before the shell moves on to the next search directory.
Once the command shell resolves the command name either to an internal
command or an external executable file, it executes the command as follows:
• If the command is internal, the shell executes it directly.
• If the command is a 1 6-bit or 32-bit Windows GUI executable program,
the shell runs the program but does not wait for the command to com
plete.
• If the command is a 32-bit console application, or a 1 6-bit MS-DOS
application, the shell runs the command in the current console window
and waits for the command to complete.
• If the command is a script file ( .BAT or .CMD), the shell switches to
script mode and begins executing the script.
Chapter 2: The Windows NT Command Shell 41
File Associations
Windows NT provides a database, in the system registry, which allows files to
be associated with a particular application. The primary use of this association
is called automatic application launching. This feature is used extensively in the
GUI environment: whenever a data file or document is double-clicked, the
associated application automatically launches, and the specified file or docu
ment then opens within that application.
File associations are also applicable to the command shell environment. For
example, suppose Microsoft Word is installed on a computer. During installa
tion of Word, .DOC files are associated with the Word application. Once this
is done, it is possible to launch Word and open a .DOC file from a shell com
mand simply by typing its name. For example:
C : \ >c : \docs\ letter . doc
In fact, the command shell applies the same rules when opening a document or
data file as it does when searching for any external command. Thus, in the pre
vious example, the shell looks for LETTER.DOC in the current directory and
in all directories specified by the search path. If the C:\DOCS directory is
added to the search path, the file LETTER.DOC can be opened in Word from
any directory, merely by typing its name. For example:
1 . C : \ docs>pat h c : \ docs ; %PATH%
2 . C : \ d ocs>cd . .
3 . C : \ >lett e r . doc
42 Part I: The Script Language
The shell first extracts the file extension, .DOC, and searches the database for
the file type associated with this file extension. Typically, this yields a file type
such as Wo rd . Document . B. The shell now uses this file type to search for the
launch command. Assume this is WI NWORD . EXE %1 . The %1 in this command is a
formal parameter, which the shell replaces with the document file name (LET
TER.DOC). So the final launch command is WI NWORD . EXE LETTER . DOC. When this
command executes, Word runs, and the LETTER.DOC file is opened.
File types are thus an intermediary between a file extension and a launch com
mand. They exist to allow multiple file extensions to be associated with the
same launch command. For example, a paint program might need to associate
.BMP, .JPG, .TIF and .TGA files with a launch command. Rather than entering
the same launch command in the database four times, the program uses a sin
gle file type and launch command, and then associates the file extensions with
this type. Any subsequent changes made to the launch command are then auto
matically applied to all associated file extensions.
The Assoc, FTYPE and ASSOCIATE commands are used to manipulate the file asso
ciation database. The ASSOC command connects a file extension with a file type,
and the FTYPE command connects a file type with a launch command.
Use the FTYPE command to create or edit a file type and associate it with a
launch command. For example:
C: \ >ftype REXX . File=c : \ re xx\ rexx . exe "%1 "
This creates the file type REXX . File and associates the prototype command
C:\REXX\REXX.EXE "%1 with the type. Notice the use of double quotes
"
around the %1 parameter. This ensures that the command is handled correctly
even if the specified document name contains spaces.
The FTYPE command can also display the current launch command for a file
type. For example:
1 . C : \ >ftype REXX . File
2. REXX . File=REXX "%1 "
Finally, the command and file type can be deleted. For example:
1 . c : \>ftype REXX . File=
2. c : \>ftype REXX . File
3 . File type ' REXX . File ' not found or no open command associated with it .
44 Part I: The Script Language
Once a file type and launch command are set up, the ASSOC command associ
ates file extensions with that file type. For example:
1 . C : \ > assoc . rex=REXX . File
2 . . rex=REXX . File
The current association of a file type is displayed using ASSOC. For example:
1 . C : \ >assoc . rex
2 . . rex=REXX . File
Notice that for both FTYPE and ASSOC, specifying the file type or file extension
only displays the current association. Specifying the file type or file extension
with a trailing = character deletes the current association.
The ASSOCIATE [ RKJ command provides a shorthand method to perform an
ASSOC and FTYPE in one step. While not as versatile as the ASSOC/FTYPE combina
tion, it is easier to use. ASSOCIATE directly associates a file extension with an
application, providing the necessary file type and launch command automati
cally. For example:
C : \>associate . rex c : \ rexx\ rexx . exe
This command directly associates .REX files with the REXX.EXE application.
The association can be deleted using the following command:
C : \>associate . rex / d
More information on the ASSOC, FTYPE and ASSOCIATE commands can be found
in the "Command Reference. "
This executes the REXX interpreter, REXX.EXE, which then interprets and
runs the script MYREXX.REX. In this example, ARG1 etc. are arguments passed
to the script.
Chapter 2: The Windows NT Command Shell 45
These commands create the needed associations, so that a .REX file launches the
REXX.EXE interpreter. Notice that by including the full path name in the proto
type command the interpreter executes without adding the C:\REXX directory
to the search path. In addition, the %1 parameter is placed in double quotes so
that . REX filenames containing spaces are correctly handled. Finally, the special
%* parameter represents all additional arguments following the first (in this case
ARG1 ARG2 ARG3) . Now, the original script command can be simplified to:
C : \ >myrexx . rex arg1 arg2 arg3
By adding the file extension .REX to the list of file extensions specified with
PATHEXT, the .REX file extension can also be made implicit. For example:
1 . C : \ >set PATHEXT=%PATHEXT% ; . REX
2 . C : \ >myrexx arg1 arg2 arg3
At this point, the MYREXX.REX script can be executed in any directory, just
by typing its name.
The first item following the START command is an optional window title,
enclosed in double quotes. By default, the START command executes the speci
fied command in a new window. In this case, the title text is used as the win
dow title.
Following the title are zero or more switches that control the operation of the
START command. A command- name must then be present, which specifies the com
mand to run. Following the command name are zero or more command argu
ments, which are passed to the specified command.
All START switches and options must appear before the command- name.
Switches and options placed after the command- name are passed, unaltered,
to the command being started.
Without any of the optional switches, the START command executes the speci
fied command. It does this as follows:
• If the command is a 1 6-bit or 32-bit Windows GUI executable program,
the START command runs the program but does not wait for the command
to complete.
• If the command is a 32-bit console application, or a 1 6-bit MS-DOS
application, the START command runs the command in a new console win
dow but does not wait for the command to complete.
• If the command is a script file ( .BAT or . CMD), or an internal command,
the START command executes a new command shell ( CMD.EXE) in a new
console window. The script or internal command is executed using the / K
switch. The START command does not wait for the command or script to
complete.
• If the command is a document or data file name associated with an appli
cation, the START command executes the appropriate application. The
START command applies the previous rules based upon the type of the
application associated with the data or document file.
Notice that the operation of the START command differs from the default com
mand shell sequence:
• First, the START command never waits for the command to complete.
• Second, all console commands start in a new console window, rather than
the current console window.
Chapter 2 : The Windows NT Command Shell 47
In this example, the command- name for the START command is actually CMD. The /C
switch and DIR command are arguments to the CMD.EXE command shell. The
START command therefore executes the command CMD /C DIR in a new console
window. When the DIR command completes, the new command shell termi
nates, and the new console window closes.
The START command is most useful when one or more of the optional switches
are used. All START switches follow the window title (if used) and precede the
command name.
The /D switch specifies a new current drive and directory for the command.
Without /D, the command inherits the drive and directory of the command
shell. Follow the / D switch with the new drive and directory. For example:
C : \>start / dc : \ book dir
The / LOW, / NORMAL, / HIGH and / REAL TIME switches set the priority class for the
command or application. By default, the START command executes all com
mands or applications at normal priority. The / LOW switch executes the applica
tion at low priority, while the / H IGH switch executes the application at high pri
ority. The / REAL TIME switch executes the application at real-time priority.
Use of the / R EAL TIME switch is strongly discouraged, as its use can com
promise Windows NT stability.
R EM
The REM (remark) command is the simplest script command because it does
nothing. Any text can follow the REM command. REM commands are used for
shell comments, and should be used liberally within a script (for example, to
clarify complex script commands and document the script logic) . The REM com
mand also suppresses the meaning of reserved shell characters within the
remark text. For example, the following is a valid remark:
C : \>rem This is valid in a REM statement : & , && , : : , •
Normally, the shell assigns special meanings to &, && etc., but in a remark com
mand these characters are treated as regular text.
The shell combines multi-line commands (like the one above) into a single
line before executing them. Therefore, the shell "sees " the command like
this:
if "%X% " =="ABC " ( rem An illegal comment ! & goto : EXIT )
The REM command will include all the text on the line, up to and includ
ing the closing parenthesis. The GOTO command is not seen as a command
at all, but instead as additional comment text.
CLS
The CLS command clears the current console window and positions the cursor
to the top left of the window. Subsequent command output begins at the top of
the window and works down the screen. The screen is cleared using the current
window colors. The CLS command is useful when a script needs to present un
cluttered output.
COLOR
The COLOR command sets the text and background colors for the console win
dow. When a console window is started, it uses the colors set using the
Console Window property sheet Colors tab, as described in chapter 1. The
COLOR command without any arguments returns the console window to these
50 Part I : The Script Language
default colors. With a single argument, the COLOR command sets the text and
background colors. The argument must be two characters long. The first char
acter specifies the background color and the second character specifies the text
color. Table 2.3 shows the color codes used.
Table 2.3. COLOR Command Color Codes
Code Color Code Color
0 Black 8 Gray
1 Blue 9 Light Blue
2 Green A Light Green
3 Aqua B Light Aqua
4 Red c Light Red
5 Purple D Light Purple
6 Yellow E Light Yellow
7 White F Bright White
For example, this command sets a pleasing white on blue color combination:
C: \ >color 1 7
T I TLE
The TITLE command changes the title bar o f the console window to the speci
fied text. The text in the corresponding button on the task bar is also changed.
The TITLE command is useful to show the progress of long or complex scripts.
It is superior to ECHO for this purpose as it does not scroll text in the console
window, and the text is visible in the task bar even when the console window
is minimized. For example:
C : \>title Backup Drive C: . . .
@
The @ command controls command echo on a line-by-line basis. By default, the
shell displays each command in a script before it is executed. Prefix a com
mand with an @ character to suppress command echo. For example:
@t itle Welcome to the sc ript !
echoes as:
C : \ > ( ) & ( title Sc ript phase 1 )
ECHO
The @ command controls command echo on a command-by-command basis.
The ECHO command controls command echo for an entire script. This command
disables command echo:
C : \ >echo off
The ECHO command is typically used at the start of a script to disable command
echo for the duration of the script. For example, many scripts begin with this
line:
@echo off
This disables echo for the entire script. The echo of the ECHO command is itself
suppressed by using the @ command. (The example above is the first special
script line that was shown in the section "Special Script Lines" in chapter 1 . )
Once echo i s disabled (or enabled) i n a script, the echo state i s maintained
within the script and within script procedures and nested scripts. The only
exception to this is nested scripts executed via a CMD or START command. These
scripts run in a new command shell, which always .starts with echo enabled.
Echo can be disabled interactively at a command prompt by entering an ECHO
OFF command. In this case, the command prompt is suppressed until echo is
enabled again. Typed commands are still echoed during entry, however.
The current echo state is used when the command shell switches from
Interactive mode to script mode to begin executing a script. Thus, if echo is
enabled interactively, the script begins with echo enabled, and vice versa.
However, the shell remembers the original interactive echo state, and recalls it
when the script completes. Therefore, after a script ends, the echo state reverts
to the value it had before the script began execution.
52 Part I: The Script Language
The ECHO command is also used to echo arbitrary text to the console window.
For example:
C : \ >echo Hello , wo rld !
If command echo is disabled, the command itself is not echoed, but the text
specified in the ECHO command is echoed. When used this way, the ECHO com
mand is the Windows NT script equivalent of the PR I NT statement found in
many languages. Typically, ECHO is used with environment variable substitution,
which is described in Chapter 3.
The ECHO command cannot be used to echo an empty line. For example:
1 . C : \ >echo
2 . ECHO is on .
As can be seen, the ECHO command displays the current state of command
echo, not an empty line. The nearest equivalent is to echo something
inconsequential, such as a single period. For example:
1 . C : \>echo
2. .
NOW [ R K ]
The NOW [ R K J command also displays arbitrary text. However, NOW prefixes the
text with the current time and date. This is useful when the time taken to exe
cute a command must be monitored. For example:
1. E : \workdir>now Start
2. Wed Oct 21 1 2 : 20 : 07 1 997
· · Start
3. E : \wo rkdir>echo Quick command
4. Quick command
5. E : \workdir>now End
6. Wed Oct 21 1 2 : 20 : 1 8 1 997
- - End
7. E: \ wo rkdir>
Command Redirection
Most console applications and commands generate output, and many accept
input. This input or output is in the form of a stream of characters (either
ANSI or Unicode) . Applications generally work with up to three streams, as
follows:
• The command input stream is used by the application or command to
read input. By default this stream comes from keys typed at the
keyboard.
Chapter 2: The Windows NT Command Shell 53
Command redirection symbols are not visible to the command. The shell
processes them before the command is executed and they are not passed as
arguments to the command. The <, >, and : symbols are reserved shell charac
ters. If these symbols must be passed as command arguments, instead of being
used as redirection symbols, then they must be escaped using the ' character.
54 Part I: The Script Language
The > redirection symbol redirects command output to the specified file. For
example:
C : \>dir >c : \ d i r . txt
This example creates a text file C:\DIR.TXT containing the output of the D I R
command. The > symbol can be placed anywhere in the command, but is typi
cally placed at the end of the command. A space is permitted between the >
symbol and the file name. If the file specified by the redirection symbol already
exists, any existing contents are deleted before the command is executed.
The » redirection symbol redirects command output to the specified file, but
concatenates the output onto the end of the file. For example:
C : \>dir >> c : \dir . txt
This example adds the output of the DIR command to the end of the file
C:\DIR.TXT. If the file specified does not exist, it is created.
The < redirection symbol redirects command input from the specified file. For
example:
C : \ >sort < c : \ d i r . txt
This command sorts the contents of the file C:\DIR.TXT and then displays the
result. A space is permitted between the < symbol and the file name. The <
symbol is used less frequently than > and », since there are few shell com
mands which accept console input.
The 2> redirection symbol redirects command error output to the specified file.
For example:
C : \ >dir 2>c : \ e rror . txt
This example redirects the error output of the DIR command to the file
C:\ERROR.TXT. A space is permitted between the 2> symbol and the file
name. Notice that this example does not redirect regular command output, so
the directory listing is still displayed. Only error output (if any) is captured to
the file.
The redirection symbols can be combined in a single command. For example:
C : \ >sort < c : \ d i r . txt >c : \ sortdi r . txt 2>c : \ erro r . txt
Chapter 2 : The Windows NT Command Shell 55
The 2 > & 1 redirection symbol redirects command error output to command out
put. This means that command error output is sent to the same destination as
command output. For example:
C : \ >dir >c : \ d ir . txt 2>&1
This command sends both command output and command error output to the
file C:\DIR.TXT.
The : (pipe) redirection symbol sends the command output of cmd1 to the com
mand input of cmd2. For example:
C: \ >dir : sort
This example sends the command output of the D I R command to the command
input of the SORT command. The output from the SORT command is then dis
played. Alternatively, the SORT output can be sent to another command. For
example:
C : \ >dir : sort : more
This example sends the command output of the DIR command to the command
input of the SORT command. Then, the command output of the SORT command
is sent to the command input of the MORE command. Finally, the command out
put of the MORE command is displayed.
When the command shell processes a pipe ( : ) symbol, it actually runs both
commands specified simultaneously. The right hand command is suspended
until the left hand command begins generating command output. Then, the left
hand command wakes up and processes the output. When this output has been
processed, the command is again suspended until more input is available. The
synchronization of both commands is handled automatically by the command
shell and Windows NT.
The pipe symbol is both a redirection symbol and a compound command sym
bol. Compound commands are discussed in the next section.
Command redirection effects are inherited by nested commands. If a command
starts with its command output redirected, and this command then starts addi
tional commands, these commands inherit the same redirection as the parent
command. This is frequently used with nested shells to capture all script output
to a file. For example:
C : \ >cmd /c myscript . bat > result . txt
This command executes the script MYSCRIPT.BAT in a new shell. Since the
new command shell has its command output redirected to the file RESULT.TXT,
56 Part I: The Script Language
all commands run by the shell (i.e. those in the script) also have their output
redirected.
By default, all command input and output is processed as ANSI (or ASCII)
characters. However, if the shell is started with the / U switch (see the " CMD "
section in the " Command Reference" ), command input and output is
processed as Unicode characters. In this case, if a command generates ANSI
output, the shell automatically converts ANSI command output to Unicode.
The &, : , ( , and ) symbols are reserved shell characters. If these symbols must
be passed as command arguments, instead of being used as compound com
mand symbols, then they must be escaped using the character.
A
The simplest compound command symbol is &. The & symbol separates multi
ple commands on a single command line. For example:
1 . C : \>echo Command 1 & echo Command 2
2 . Command 1
3 . Command 2
This example shows two ECHO commands on a single line. When & is used to
separate multiple commands, the commands execute one at a time, starting
with the first command. Each command runs to completion before the next
command executes.
Chapter 2 : The Windows NT Command Shell 57
Any number o f commands can b e placed o n a single line using the & symbol.
For example:
C : \>dir c : \ bin >files . txt & dir c : \ dos >>files . txt & type files . txt
This example accumulates the results of two DIR commands into the file
FILES.TXT and then displays the contents of this file. This example also shows
that command redirection symbols can be used with each individual command
in a compound command.
The && and : : compound command symbols provide conditional command
execution. The first (left) command is executed. If the && symbol is used, the
second command executes only if the first command completed successfully. If
the : : symbol is used, the second command executes only if the first command
did not complete successfully. A command completes successfully if it returns
an exit code of 0 or no exit code at all. Exit codes are discussed in chapter 3 .
For example:
C : \ >verify on :: echo Verify command failed ! !
Since the VER I FY command executed successfully, the ECHO command was not
executed. However, in this example:
1 . C : \>verify ox : : echo Verify command failed ! !
2 . An incorrect parameter was
3 . ente red for the command .
4 . Verify command failed ! !
The ECHO command was executed because the VER I FY command syntax was
incorrect, causing the command to exit with a non-zero error code.
Multiple commands can be chained together using additional && and : : com
pound command symbols. For example:
C : \ >dir && copy a b && echo OK I
The COPY command executes only if the D I R command succeeds, and the ECHO
command executes only if the COPY command succeeds.
The parentheses symbols ( and ) are used to resolve command ambiguities and
indicate the binding of compound command and redirection symbols. They are
also used in the I F command and to specify multi-line commands.
For example, the following command collects two directory listings into the file
FILES.TXT:
C : \ >dir • . exe >files . txt & dir • . com >>files . txt
The following command might appear to do the same, but in fact it does not
work:
C : \ >dir • . exe & dir • . com >files . txt
58 Part I: The Script Language
This second example fails because the command redirection symbols have a
higher precedence than the compound command symbols. The shell interprets
this command as follows:
1 . C : \>dir * . exe
2 . C : \ >dir * . com >files . txt
This displays the result of the first D I R command in the console window
which is not the desired effect.
The second example can be corrected by using parentheses to alter the binding
of the various symbols, as follows:
C : \ > ( dir * . exe & dir * . com) >files . txt
This compound command executes two DIR commands, one after the other.
The output of both commands is redirected into the file FILES.TXT. The
parentheses change the binding of the command symbols. Notice that this com
mand is far cleaner than the earlier example, and that the file FILES.TXT is
only specified once in the command.
Parentheses can be nested to specify arbitrarily complex compound commands.
For example:
C : \ > ( ( echo comman d 1 ) & ( echo command2 ) ) && ( echo command 3 )
Notice that the second ECHO command did not echo the closing parenthesis. In
this case, the shell treats this as the end of the command, and this parenthesis is
not passed as part the ECHO arguments. In the first case, the command itself
does not begin with a parenthesis, and so the end of line marks the end of the
command. In this case, the entire ( command ) text is passed to the ECHO command.
Parentheses can also be used to enter multi-line commands. If a command line
ends with one or more sets of unbalanced parentheses, the command line is
assumed to continue on the next line. If the command was entered interactive
ly, the shell prompts for more input until all parentheses balance. If the com
mand is part of a script, the shell reads additional script lines until all the
parentheses balance. For example:
1 . C: \>(
2 . More?echo command1
Chapter 2 : The Windows NT Command Shell 59
3 . More?echo command2
4. More? )
5 . command1
6. command2
The first line consists only of an open parenthesis. The shell detects this, and
prompts for more input. Next, two ECHO commands are entered. Finally, a clos
ing parenthesis balances the opening parenthesis and the command is complete.
The shell then executes the compound command, which executes the two indi
vidual ECHO commands.
Individual commands do not span lines in multi-line commands. The end of a
physical line always terminates a simple command (either as typed or as
entered in a script file). Notice in the preceding example how the end of the
physical line terminated each ECHO command.
Compound commands and multi-line commands are particularly useful with I F
and FOR statements. These commands are described in Chapter 4 . For example:
1 . if exist * . bak (
2. echo Deleteing * . BAK files . . .
3. del * . bak
4.
The I F command executes the following command if one or more .BAK files
exist in the current directory. Parentheses are used to execute a compound
multi-line command. In this example, the ECHO command displays a warning,
and then the DEL command deletes the files. The indentation here is not manda
tory, but does help to indicate the flow of control.
HH
Using a parenthesis, even when not strictly needed, is a useful way to
increase script readability, and makes explicit the command execution
precedence rules.
MOR E
The MOR E command breaks its command input into pages. A page is the same
number of lines as the console window. For example:
C: \>dir : more
This command displays the current directory, one page at a time. Press the
spacebar to advance to the next page. The MORE command supports several
switches to control the output format. These are detailed in the MORE section of
the " Command Reference. "
SORT
The SORT command sorts its command input alpha-numerically, using the ASCII
collating sequence. For example:
C : \>sort <dat a . txt
This command sorts the contents of file DATA.TXT and displays the result. By
default, the SORT command sorts in ascending order. The / R switch sorts in
reverse (descending) order. Lines are sorted based on the data at the start of
each line. Use the +n switch to sort based on data starting at column n on each
line. For example:
C : \>dir : sort +1 4
This command sorts the output of the DIR command based on data starting at
column 14 on each line.
F I ND
The F I ND command filters command input, passing to its command output only
those lines which contain a specified string. For example:
Chapter 2: The Windows NT Command Shell 61
This command filters only directory lines from the output of the D I R command.
The F I N D command supports several switches to control the filtering process
these are detailed in the F I N D topic of the " Command Reference. " One useful
switch is / C, which outputs only a count of the lines which match the string,
instead of the lines themselves. For example:
C : \ >dir : find ' <DIR> " / C
CL I P [ RK ]
The C L I P [ RKJ command places its command input into the clipboard. For
example:
C: \ >dir : clip
This command dumps the output of the DIR command into the clipboard. Once
in the clipboard, the text can be pasted into any Windows application.
The Schedule Service does not execute the logon script, so drive X: is not avail
able. The first solution to this problem uses the NET command to explicitly map
drive X: in the script. For example:
1 . net use x : \ \ serve r \ common
2 . copy x : \ myfiles \ * . bak c : \ backups
3. net use x: /delete
Virtually all built-in commands, and most external commands, accept UNC
names as well as path names as arguments.
The final stage to prepare the Schedule Service for use is starting the service.
Typically, the start-up options for this service are changed to require the service
to automatically start whenever Windows NT boots. Both of these operations
can be accomplished via the Control Panel Services applet. Figure 2.6 shows
the Services applet running. The Schedule Service is named Schedule. Click the
Start button to start the service, or the Stop button to stop the service.
Click the Startup button to set service startup options. Figure 2. 7 shows the
startup options dialog box. Typically, the Startup Type should be Automatic,
and the Log On As option should be the account setup specifically for the
schedule service.
Chapter 2: The Windows NT Command Shell 63
Once the Schedule Service is running, commands can be scheduled using either
the AT command or the SOON [ RK J command. Refer to the " Command
Reference" for a detailed description of these commands. The Windows NT
Resource Kit also provides a GUI interface to the Schedule Service, called
WINAT.
By default, all commands manage the schedule service on the local comput
AT
er. Specify the computer name as the first argument to manage the service on
another computer. For example, this command lists all scheduled commands
on the current computer:
1 . C : \ >at
2 . Status ID Day Time Command Line
3. . .. .. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - .. - - - - - - - - - - - - - - - - - - - - - - - - - · .. . .. .. .. .. - - - - - - - -
Enter an AT command and specify the execution time and the command to exe
cute to schedule a command for execution. For example:
C : \ >at 23 : 00 : 00 / every : monday cmd /c sysbku p . bat
• Variable basics
Learn how to set and retrieve variable values. Additionally, the variable
substitution mechanism and variable scoping rules are described.
• Advanced SET commands
Here, the use of SET to compute arithmetic expressions is detailed.
• Special variable syntax
This section details the string substitution and indexing mechanisms, and
develops a simple variable array scheme.
• Script parameters and arguments
The parameter passing mechanisms are described, along with advanced
features such as parameter qualifiers.
Variable Basics
As Chapter 1 described, a basic script is simply a text file containing a record
of shell commands. Executing a basic script produces an effect identical to typ
ing the commands directly into a command shell. If this were all scripts could
do, they would be of limited value. Fortunately, the command shell includes
three features that enable scripts to go beyond simple command re-entry. These
are:
• Environment variables, which provide data storage for scripts.
• Parameter substitution, which passes script arguments into the body of
the script.
• Control flow, such as GOTO and CALL, which enable scripts to branch and
loop, and also to execute commands conditionally. Control flow is the
subject of Chapter 4.
66 Part I: The Script Language
The use of variables in a script is the key to virtually all advanced scripts.
Variables allow a script to maintain state information, and act intelligently on
that state. For example, a script could use the NET USER command to capture a
list of all users into a variable array, and then perform additional processing
steps for each user specified in the array.
In Windows NT, each running application (process) contains a set of strings
called the application environment. Each string is named and can contain any
arbitrary text. These named strings are called environment variables, or simply
variables. The name of each string is the variable name, and the string itself
forms the variable value. Windows NT provides Application Program
Interfaces (APis) to allow an application to recover the contents of variables by
name and to change variable values or create new variables.
When Windows NT starts a new process, the process inherits the environment
of the process that created it (its parent process). The new environment is
copied from the parent process. This means that any changes the process
makes to its environment are local to the process and do not effect the parent
or any other processes running in the system.
These same rules apply to the Windows NT command shell. When a command
shell starts, it inherits the environment of its parent process, which is typically
the Windows Explorer. Any changes the shell makes to its environment vari
ables are local to that shell. If multiple shells are running at the same time,
each shell has its own unique environment. Similarly, when the shell starts an
application or external command, that application or command inherits the
current shell environment.
The / I switch of the START command modifies the default inheritance behavior.
When the START command is used with the / I switch, the command executed
inherits the shell environment as it existed when the command shell started
execution. Thus, any changes made to the shell's environment (via the SET com
mand) are not passed to the executed command.
Variables are defined and their values set using the SET command, described in
the following sections. Variable values are recalled using a process known as
variable substitution, which is described in subsequent sections.
Another point to note is that the variable values displayed in the value lists are
shown after variable substitution has occurred, but the values displayed in the
Value edit box are shown before variable substitution has occurred. To see an
example of this, examine the value of the TEMP user variable.
The dialog box does not edit the environment itself. Instead, it edits the reg
istry keys that are used to initialize the environment (as previously described).
Therefore, changes made to user variables are not applied until the next logon,
and changes made to system variables are not applied until the next system
restart.
Setting Variables
The SET command is used to create, delete, change, and display the value of
environment variables. The command alters variables in the current shell's
environment only. To display a list of all environment variables, use SET with
out any arguments. For example:
1 . C : \ >set
2. BLASTER=A220 15 01 H 5 P330 E620 TS
3 . COMPUTERNAME=GODZILLA
4 . ComSpec=D : \WINNT \ system32 \ cmd . exe
5 . Etc .
To display a partial list of variables, follow the SET command with the first few
characters of a variable name. The command displays all variables whose name
begins with these characters. For example:
1 . C : \ >set PROCESSOR
2 . PROCESSOR_ARCHITECTURE=x86
3. PROCESSOR_IDENTIF IER=x86 Family 6 Model 3 Stepping 3, Genuine intel
70 Part I: The Script Language
4 . PROCESSOR_LEVEL=6
5 . PROCESSOR_REVISION=0303
To create a new variable or change the value of an existing variable, follow the
SET command with the name of the variable, an equal sign, and the value of the
variable. For example:
1 . C : \ >set X= 1 4
2 . C : \ >set SRCDIR=c : \
3 . C : \ >set DEFAULT_DESTINATION=c : \ P rogram File s \ TestApp \ Data
The last example shows that everything following the = sign forms the variable
value, including spaces.
To delete an existing variable, follow the SET command with the name of the
variable to delete and an equal sign. For example:
1. C : \ >set LOCATION
2. LOCATION=d : \ bin
3. C : \ >set LOCATION=
4. C : \ >set LOCATION
5. Environment variable LOCATION not defined
Notice the difference between displaying the current value of a variable (the
first command in the previous example) and deleting the variable (the second
command using set name= ) •
Virtually any character can be used for a variable name. For example, the
following command creates a variable named _% 1 :
C : \>set _% 1 =An odd variable name
The shell accepts the space character as a valid part of a variable name.
This can lead to some odd consequences. For example, this command
defines a variable called zz:
C : \ > s e t ZZ= 1 2
1. C : \ >set zz =13
2 . C : \ > set ZZ
3 . ZZ= 1 2
4 . zz =13
The rule the SET command follows is that everything from the first non
blank character on the line up to, but not including, the first = character is
the name of the variable. One common mistake in scripts is accidentally
placing a space before the = sign in a SET command. For example:
1. s e t DEFD I R= c : \ s r c
2. if " %1 " == " X " s e t DEF D I R =c : \ s r c 2
Presumably, the intention of the second line is to redefine the DEFD I R vari
able. However, the extra space instead defines a new variable called
" DEFDIR (with a trailing space) and leaves the original DEFDIR intact.
"
Bugs such as these can be very tricky to track down. The rule of thumb is
never leave a space before the = sign in a SET command.
When creating or changing a variable with the SET command, all of the com
mand text after the first = sign comprises the variables value. This includes any
leading and trailing spaces and tabs. Reserved shell characters (defined in
Chapter 2) such as & can be placed in the command text either by escaping
them or by placing the variable value in double quotes. For example:
1 . C : \>set ZZ=rock ·& roll
2 . C : \ >set ZZ
3. ZZ=rock & roll
4 . C : \ >set ZZ= " rock & roll "
5 . C : \>set zz
6 . ZZ= " rock & roll "
Notice that using double quotes to include reserved shell characters also
includes the double quotes themselves in the variable value. This happens
because all text after the = sign is taken as the variable value, including double
quote characters.
The I F DEF I N ED command is used to test to see if a variable is defined or not.
For example:
1 . C : \>set ZZ=1
2 . C : \ >if defined ZZ echo ZZ is defined
3 . ZZ is defined
4. C: \>set ZZ=
5 . C : \ >if not defined ZZ echo ZZ not defined
6. ZZ not defined
Variable Substitution
Once a variable is defined, it can be used within typed commands and scripts
using a process known as variable substitution. Variable substitution is the sin
gle most powerful tool available for writing scripts, as it is the primary mecha
nism for a script to modify its behavior based on state information. To use
variable substitution, place the name of a defined variable, bracketed by per
cent signs, anywhere in a command. For example:
1 . C : \ >set ZZ=HELLO
2 . C : \ >echo Var ZZ contains %ZZ%
3 . Var zz contains HELLO
Notice what happened to the output of the ECHO command in the previous
example: The variable name, enclosed in percent signs, is replaced by the value
of the variable. This substitution process is valid for all variables, including
those defined by the system. For example:
1 . C : \ >echo Good morning , %USERNAME% 1
2 . Good mo rning , TimH I
Variables used in this and similar ways can be defined in the script, or defined
by entering commands into a command shell before the script is run. In addi
tion, one script can define variables containing information needed by another
script, and then execute this second script as a procedure (this is described in
Chapter 3 : Script Parameters and Variables 73
detail in Chapter 4 ). When used in this manner, variables can be used to pass
arguments to procedures.
Variable substitution is powerful because it occurs before the shell interprets a
command. Therefore, a command can be built up from command text frag
ments contained in variables. This allows a script to adapt itself to different
circumstances. For example:
1 . set NETSW=
2 . if "%0S% " == "Windows_NT " set NETSW= / persistent : no
3 . net use d : \ \ dataserve r \ f iles %NETSW%
This script fragment executes a N ET USE command to map a network share. The
N ET USE command is available on Windows NT and Windows 95, but the latter
operating system (OS) does not support the / PERS I STENT switch. The I F com
mand in the example tests to see if the operating system is Windows NT. If it
is, the N ETSW variable is set. If not, the variable remains empty. This means that
when the N ET USE command executes on Windows 95, the command will be:
net use d : \ \ dataserve r \ f iles
When the shell processes a command, variable substitution occurs before all
other syntax processing. Thus, a shell variable can contain any syntax or syn
tax fragment allowed in a command. For example:
1. C : \ >set AND= ·&
2. C : \ >echo one %AND% echo two
3. one
4. two
The text is echoed literally. In script mode (when commands are read from a
script file), the variable name and bracketing percent signs are deleted (i.e.,
replaced by nothing). For example:
1 . set UNDEF=
2 . echo Undef is %UNDEF%
Similarly, the handling of percent signs differs depending upon the shell mode.
In interactive mode, any percent sign not explicitly part of a variable substitu
tion is treated literally. For example:
1 . C : \>echo % by it self is o k , as is %% or 1 00%
2 . % by itself is o k , as is %% or 1 00%
In script mode, however, all literal percent characters must be doubled. For
example:
echo Use %% to enter a literal percent sign in a script
Recursive Substitution
Variable substitution is not recursive. If a variable's value in turn contains vari
ables to substitute, these will not be substituted when the variable is itself sub
stituted. For example:
1 . C : \ >set zz= ·%vv·%
2 . C : \ >set YY=Any t ext
3 . C: \ >echo %ZZ%
4 . %VY%
In this example, the variable zz contains the literal text " %VY% " as a result of the
escaped percent signs. In the last line, the shell substitutes the variable zz with
the literal text " %VY% " , but does not then attempt to substitute the variable VY.
In other words, the shell does not rescan substituted text for additional vari
able substitutions.
There is one exception to this non-recursive rule: the CALL command (which is
described in Chapter 4 ). For example:
1. set ZZ=%%YY%%
2. set YY=Any Text
3. call : SUB1 "%ZZ% "
4. goto : EOF
5 . : SUB1
6 . echo %1
7 . goto : EOF
Chapter 3 : Script Parameters and Variables 75
As in the previous example, zz contains the literal text " %YY% " . However, the
ECHO command in procedure sue1 actually echoes the contents of the variable
YY. This is because the CALL command performs an additional level of variable
substitution. First, the shell expands %ZZ% into %YY% (literally). Then, the addi
tional level of substitution expands %YY% into " An y Text " .
The lack of recursion in variable substitution can be a difficulty when more
advanced scripts are developed. In particular, accessing variables indirectly (for
example, in arrays) or accessing variables whose name is passed as an argu
ment to a procedure is difficult. Chapter 4 develops a technique to overcome
this using the FOR command, and this technique is presented as the : RESOLVE
procedure in the _MTPLIB.BAT library in Chapter 5. Many of the example
scripts in Part II of this book use this procedure.
The RET variable is used extensively in the example scripts developed in Part II
of this book.
76 Part I: The Script Language
The open parenthesis starts a multi-line command. The SET command defines a
variable called CP that contains a closing parenthesis character. On the next
line, the %CP% is an attempt to end the command by expanding %CP% to a closing
parenthesis. However, the prior SET command has not yet been executed, so CP
is not yet defined, and %CP% is not expanded. Finally, after the closing parenthe
sis is entered, the SET command is executed, and CP is then defined.
1 . Set X=Tim
2. (
3. set X=John
4. set X=%X% Doe
5.
What is the value of the variable x after these lines are executed?
Surprisingly, perhaps, the answer is Tim Doe. The first line simply sets the
variable x to Tim. Then, the multi-line command is executed. The entire
command is read by the shell, and processed as one command:
( set X=John & set X=%X% Doe )
Now the commands are executed. The first SET command sets X to J o hn,
but the next SET command immediately changes x back to Tim Doe.
To avoid problems such as this, the rule is to never attempt to use the
value of a variable in the same multi-line command that sets the value.
Variable Scope
The previously described rules governing environment inheritance limit the
scope of environment variables. Because each application (and hence each com
mand shell) inherits its own environment, SET commands in each shell affect
only the current shell environment, and not any other (unless that environment
is then inherited by another command) .
Changes to variables made with the SET command are global within a com
mand shell. Any scripts run by the command shell have access to all shell
variables defined within the shell. Changes, additions, or deletions to the
environment made by a script persist within the command shell after the script
finishes. For example, if a script creates a new variable called SRC1 , then this
variable will exist in the environment when the script ends, and can be
accessed interactively or within subsequent scripts.
One way to change this behavior is to execute a script within a nested com
mand shell. For example, to execute the script TEST.BAT within a nested
command shell, enter the following:
C : \ >cmd Jc test . bat
The new shell inherits the current environment and begins executing the script.
However, because the new shell is a distinct process, changes made to the envi
ronment within the script are lost when the script (and the nested command
78 Part I: The Script Language
shell) terminates. Using a nested shell in this way protects the current environ
ment from changes made within a script. In fact, the current shell is also pro
tected in the same way from other state changes made by the script, such as
changing the current drive and directory.
A similar technique uses the START command to run a script. For example:
C : \ >start test . bat
This executes the TEST.BAT script in a nested command shell in a new win
dow. Use the / I switch with the START command to cause the nested command
shell to inherit the same environment that the parent shell itself inherited. As
with all environment inheritance, the nested shell inherits a copy of all
variables.
Within the " brackets" formed by the SETLOCAL and ENDLOCAL commands, SET
commands have a local scope. Thus, after the ENDLOCAL command executes in
the script fragment above, the zz variable is restored to the value it had before
the SETLOCAL command was executed. (If the zz variable did not exist before the
SET LOCAL command was executed, it will be deleted by the ENDLOCAL command. )
SETLOCAL and ENDLOCAL are used in a similar way within script procedures
(described in Chapter 4). By bracketing the entire procedure within a
SETLOCALIENDLOCAL pair, all variable manipulations are made local to the
procedure.
Chapter 3 : Script Parameters and Variables 79
The SETLOCAL and ENDLOCAL commands can be nested to create additional local
scopes. For example, a procedure with a local scope can call another procedure
that contains a local scope. In each case, the ENDLOCAL command restores the
most recently saved snapshot. The maximum nesting level for SETLOCALIENDLOCAL
is 32 levels.
Variable Tunneling
Using local scopes in procedures is strongly encouraged. (Procedures are cov
ered fully in Chapter 4.) However, SETLOCAL and ENDLOCAL within a procedure
can cause difficulties. Consider this simple procedure:
1 . : SUB1
2.
3.
4 . set RET=500
5 . goto : EOF
This example defines a procedure called SUB1 , which sets the variable RET to
500 and then returns to the caller. As already described, the RET variable is typ
ically used to hold return values from procedures.
Using SETLOCAL and ENDLOCAL to define a local scope enhances this simple proce
dure. For example:
1 . : SUB1
2 . setlocal
3.
4.
5 . set RET=500
6 . end local
7 . goto : EOF
However, as shown, this procedure will not work properly. The problem is that
the SET command that sets the return value, RET, is executed before the ENDLOCAL
command. As a result, ENDLOCAL deletes the RET variable, along with all other
changes made to the environment, before the procedure returns. This effec
tively wipes out the return value from the SUB1 procedure.
One solution to this problem is to move the SET command so that it is after the
ENDLOCAL command. For example:
1 . : SUB1
2 . setlocal
3.
4.
5 . end local
6 . set RET=500
7 . goto : EOF
80 Part I: The Script Language
For this simple procedure, the alteration works correctly. However, for more
complex procedures, the solution fails. Consider this procedure:
01 . : SUB2
02 . setlocal
03 . if " %DIR% " == " 1 " set RET=4
04 .
05 .
06 . if " %P45% " == " NEW" set RET=1 4
07 . if " %AUTOSW% " == " 3 " set RET=56
08 .
09 .
10. endlocal
11. goto : EOF
The procedure uses SETLOCAL and ENDLOCAL commands to create a local scope,
and sets the return value in RET to a different value depending upon the result
of several IF commands. As before, this procedure does not work as written,
because the ENDLOCAL command deletes the RET variable. In this case, however,
the SET commands cannot be moved to below the ENDLOCAL command, because
they are an integral part of the procedure logic. The SET command somehow
has to be both before and after the ENDLOCAL command.
Fortunately, there is a simple trick to overcome this problem, which can be
thought of as variable tunneling. The SUB2 procedure is re-written as follows:
01 . : SUB2
02 . setlocal
03 . if " %DIR% " == " 1 " set RET=4
04 .
05 .
06 . if " %P45% " == " NEW" set RET= 1 4
07 .
08 . if " %AUTOSW% " == " 3 " set RET=56
09 .
10.
11. endlocal & set RET=%RET%
12. goto : EOF
This version of SUB2 is identical to the previous version except for the addition
of the extra SET command after the ENDLOCAL command. The trick used here
involves the order in which the shell evaluates a command. When the shell
reaches the line containing the ENDLOCAL and SET commands, the RET variable
contains the desired return value. Suppose RET contains the value "56. " The
shell then executes the command. As entered in the script file, the command
consists of:
endlocal & set RET=%RET%
Chapter 3 : Script Parameters and Variables 81
As previously described, the first operation the shell performs o n any command
text is variable substitution. In this case, the shell replaces %RET% with the value
56. So, after variable substitution, the command appears as:
endlocal & set RET=56
This sets the RET variable to 5 6. Notice that this is executed after the ENDLOCAL
command, and it restores the RET variable to the value it had before the local
scope was deleted.
This trick of assigning a variable with its own value on the same line as the
ENDLOCAL command allows a variable's value to "tunnel" through a local scope.
It can be used for multiple return values. For example:
endlocal & set RET=%RET% & set SRCDIR=%SRCDIR%
This example tunnels the RET and SRCD I R variables out of the local scope.
Special Variables
The command shell and Windows NT define and use several special variables.
In addition, some commands also make use of variables. For example, the D I R
command reads additional command switches from the DI RCMD variable.
The COMSPEC variable always contains the full path of the command shell
executable. It is considered good practice to use this variable to refer to the
command shell, rather than simply using CMD.EXE or CMD. This avoids
the possibility of the wrong version of CMD.EXE being executed when multi
ple OSs are included in the search path. For example, replace this line in a
script:
cmd /c test . bat
The PATH and PATHEXT variables are used when the shell searches for a command
to execute. This process is described in detail in Chapter 2. Chapter 2 also
describes the PROMPT variable and its use to define the shell command prompt.
82 Part I: The Script Language
Finally, although the RET variable is not technically a special variable, by com
mon convention this variable is used to pass a return value from a procedure
back to the calling script. Following this convention can help to make scripts
more easily understood.
Advanced S ET Commands
The basic SET command is used to set the value of a variable to a literal text
value. The advanced SET command evaluates an arithmetic expression and can
assign the numeric result of this expression to a variable. To enter an arith
metic SET command use the I A switch. For example:
1 . C : \ >set /a 1 +2
2. 3
As this example shows, the SET command displays the numeric result of the
expression-in this case 1 + 2 . This only occurs in interactive mode. In script
mode, expression results are evaluated, but not displayed.
Expressions are evaluated using 32-bit signed integer arithmetic. Overflows are
not detected, and wrap-around from 2147483647 to -2147483648 and vice
versa is allowed.
Care should be taken when using the modulus operator. The shell uses the %
sign for variable substitution. Therefore, to enter a modulus operator in a
script, either escape it or use two percent characters. For example:
set /a 1 3 '% 3
Generally, spaces are ignored within expressions and can be used freely to
improve readability.
The = operator sets the variable to the expression result. The value is stored as
a decimal string of digits, not a binary value (environment variables are always
84 Part I: The Script Language
strings). Once set, the variable can be used in variable substitution like any
other variable. For example:
1 . C : \ >Set /a X=900* 1 3
2 . C : \>echo Result i s %X%
3 . Result is 1 1 700
Variables that contain numeric values can be used within expressions. These
variables do not need to be placed within percent signs. For example:
1. C : \ >set /a X=1 4
2. C : \ >set /a X*1 0
3. 1 40
4. c : \ >set /a %X%* 1 0
5. 1 40
Generally, percent signs are not used, as this improves readability and avoids
evaluation order ambiguities (described in the following section). In addition,
undefined variables are treated slightly differently, depending upon the presence
or absence of percent signs. When used with percent signs, normal variable
substitution replaces undefined variables with nothing. When used without per
cent signs, the SET command assumes any undefined variables have the value
zero. For example:
1. C : \>set X=1 4
2. C : \ >set Y=
3. C : \ >set /a X + Y
4. 14
5. C : \ >set / a %X% + %Y%
6 . Missing operand .
The variable Y in this example is undefined. The first SET I A command simply
treats this as a zero value. The second SET I A command substitutes a null value
for %Y%, resulting in a missing operand error.
When the shell obtains a numeric value from a variable, it attempts to locate a
valid number at the start of the value of the variable. If no number is found,
the shell uses the value zero. For example:
1 . C : \ >set X=1 4 dollars
2 . C : \ >set Y=1 9 dollars
3. C : \ >set Z=and cents
4. C : \ >set / a X+Y+Z
5 . 33
Because the variable v does not begin with a number, i t yields zero when used
in an expression.
Number Formats
All numbers are assumed to be decimal by default. Expression results are
always displayed in decimal, and values assigned to variables using the = opera
tor are always decimal.
Hexadecimal (base 1 6) numbers can be entered in an expression by prefixing
the number with 0x. For example, the hexadecimal number Ox1 00 is equivalent
to the decimal number 256. Hexadecimal numbers can contain the digits " O "
t o " 9 " and the letters " A " t o "F" o r "a" to "f. "
Octal (base 8) numbers can b e entered in an expression by prefixing the num
ber with a leading zero. For example, the octal number 014 is equivalent to the
decimal number 12. Octal numbers can contain the digits " 0 " to " 7" only.
The shell applies the same number format rules to numbers stored in variables.
Thus, variables can contain strings representing decimal, hexadecimal, octal or
binary numbers. For example:
1 . C : \>set X=0x 1 00
2 . C : \ >set Y=1 2
3 . C : \ >set / a X+Y
4 . 268
Although variables can contain numbers in any base, the = operator always
stores decimal values. For example:
1 . C : \ >set X=0x1 00
2 . C : \ >set / a X=X
3 . 256
4 . c : \>set x
5 . X=256
In this example, the variable x is initially set to the string 0x1 00. The second SET
command evaluates this value as an expression and assigns the result back to the ·
variable x. This replaces x with the decimal result of the expression, which is 256.
is evaluated as
(A « C) & D
Logical bit operators are evaluated as a group after the arithmetic operators.
For example,
A « C + D
is evaluated as
A « (C + D )
The left shift and right shift operators logically shift the bits in a 32-bit value
to the left or the right. Zero bits are shifted in at the left or right as the bits are
shifted. For example, 0 x 1 00 « 2 shifts the value Ox1 00 (256 decimal) to the
left by 2 bits. This yields the value 1 024.
The logical AND, logical OR, and logical exclusive OR perform " bitwise" log
ical operations by applying the specified logical operator to each bit in the
operands in parallel. For example, 0 b 1 001 & 0b0 1 0 1 yields the value 1, which is
ObOOO l in binary.
All of the logical bit operators use characters that are reserved shell characters.
Therefore, all these operators must be escaped when used in an expression. For
example:
C : \ >set / a x = Y ·<·< 3 .
Assignment Operators
The basic assignment operator assigns the result of an expression to a variable
as a decimal number. The assignment operators act as shorthand for a special
type of expression. For example, the expression:
1 . C : \ >set X= 1
2 . C : \ >set / a X = X + 1
Both these SET commands perform the same action: they increment the value in
the x variable. The second SET command uses an assignment operator, which
provides a more compact expression.
Assignment operators work as follows:
1 . The expression to the right of the assignment operator is evaluated to
yield a number (in the previous example, 1 ).
2. The operation specified by the assignment operator ( + in the previous
example) is applied between the expression result ( 1 ) , and the value of the
variable specified on the left of the operator (in the previous example, x,
which has the value 1 ) .
3. The result of this expression (x+1 , which yields 2) is then stored back into
the same variable. This assigns the value 2 to the variable x.
The following example multiplies the value in X by 12, placing the result back
into X:
C : \ >set / a X *= 9+3
88 Part I: The Script Language
Assignment operators exist for all standard operators; for example, *= for mul
tiplication, &= for logical AND, and so on.
This example increments both x and Y using assignment operators, and assigns
the sum of these two variables to z. When multiple expressions are placed in a
single SET command, only the result of the last expression is displayed.
Expressions are evaluated from left to right. In the previous example, both x
and Y are incremented before the last expression is evaluated. Thus, z is
assigned the value 4.
Evaluating multiple expressions in a single command is one case where the use
of percent signs can make a considerable difference to the result of an expres
sion. The variable z is assigned the value 4 because the two variables x and v
are incremented to 2 before the expression Z=X+Y is evaluated. However, consid
er this example:
1. C : \>set X=1
2. C : \ >set Y=1
3. C : \ >set / a X+=1 , Y+=1 , Z=%X% + %Y%
4. 2
String Substitution
String substitution is an optional feature of variable substitution. String substi
tution enhances variable substation by replacing, in the variable text, occur
rences of a specified string with another string. To specify string substitution,
use the following syntax:
\var - name : string 1 =s tring2\
Replace var - name with the name of the variable to be substituted. The variable
text is then scanned for occurrences of the string string 1 . Each occurrence is
then replaced with the string string2 before the value is substituted in the com
mand text. For example:
1. C : \>set X=A normal variable
2. c: \>echo \X\
3. A normal variable
4. C : \ >echo \X : a=b\
5. b normbl vbribble
In this example, the variable substitution %X : a=b% replaces all occurrences of the
letter "a" with the letter " b, " as seen in the result of the ECHO command.
Notice that both upper and lower case letters are replaced-string substitution
is not case sensitive.
String substitution does not alter the value of the variable being substituted,
only the command text into which the substitution occurs. Thus, after the
%X : a=b% substitution, the variable x is unchanged.
Substitution is not limited to single characters, nor do string 1 and string2 need
to be the same length. For example:
1. C : \ >set PATH=c : \ bin ; c : \dos ; c : \winnt
2. C : \ >set PATH=%PATH : c : =d : \
3. C : \ >set PATH
4. PATH=d : \ bin ; d : \dos ; d : \winnt
This example replaces all instances of the string c : with d : in the PATH variable,
and then uses a SET command to assign the result back to the PATH variable.
The replacement string, string2, can be empty. In this case, all occurrences of
the search string string 1 are deleted. For example:
1 . C : \>set X=1 , 200 , 456
2 . C : \ >echo \X : , =\
3 . 1 200456
90 Part I: The Script Language
This substitution strips all comma characters from the variable x in the ECHO
command.
String Indexing
String indexing is similar to string substitution. It operates during variable sub
stitution, and causes only a fixed portion of the variable's value to be substituted
into the command text. To specify string indexing, use the following syntax:
%var -name : -n , len%
Replace var - name with the name of the variable to be substituted. A portion of
the variable, starting at character index n and of length len characters, is then
substituted into the command text. For example:
1 . C : \ >set X= . CMD ; . BAT ; . EXE
2 . C : \>echo %X : -5 , 4%
3 . . BAT
The index of the first character in x is zero. Therefore, the index of the . in
. BAT in x (the sixth character) is 5 . The length of the string . BAT is 4 characters,
so the result of the %X : -5 , 4% substitution is . BAT, which is shown by the ECHO
command output.
Do not forget to follow the variable name with a colon and tilde charac
ter : - when using string indexing. If you leave out the tilde, the shell
interprets the variable substitution as string substitution. This can have
unexpected and unpleasant results.
The l en argument in a string index can be omitted, in which case all variable
text starting at index n and continuing to the end of the variable value is
substituted. For example:
1 . C : \ >set X=1 234567890
2 . C : \ >echo %X : -4%
3 . 567890
In this example only eight characters are substituted, even though len calls for
20, because the end of the variable is reached first.
Chapter 3 : Script Parameters and Variables 91
This creates two new array entries in the array USERS. Array element 12 is set
to the value MarkP and element 13 is set to Karenv. This use of variable names is
just a convention: To the command shell, the variable USERS_1 2_ is a normal
variable, not part of an array.
Individual elements can also be set indirectly. For example:
1 . C : \ >set X= 1 4
2 . C : \ >set USERS_%X%_=BobW
This macro can then be used to define new elements. For example:
C : \ >seta USERS 9 KarlM
Although the macro is more elegant than the direct SET command, it has one
disadvantage. If the value to be set contains spaces, it must be enclosed in dou
ble quotes, and these double quotes become part of the value. For example:
1 . C : \ >seta USERS 17 " Karen Voester "
2 . C : \ >set USERS_1 7_
3 . USERS_1 7_= " Karen Voeste r "
To display all the elements o f a n array, use the SET command with the array
name and a single underscore character only. For example:
1. C : \ >set USERS_
2. USERS_9_=Kar1M
3. USERS_1 2_=MarkP
4. USERS_1 3_=KarenV
5. USERS_1 4_=BobW
92 Part I: The Script Language
Use a FOR command to delete an entire array. The FOR command is described in
detail in Chapter 4. For example:
C: \ >for / f " delims== tokens=1 " %i in ( ' set USERS_ ' ) do @set %i=
The FOR command uses the output of the SET command to run a series of indi
vidual element delete commands. This use of the FOR command is described
fully in Chapter 4. Since this is quite a complex command, it is another ideal
candidate for a DOSKEY command macro. For example:
C : \>doskey dela=for / f " delims== tokens=1 " %i in ( ' set $ 1 _ ' ) do @set %i=
The ECHO command does not echo the contents of USERS_ 1 2_, as was intended,
because the shell does not recursively parse substituted text for additional vari
able substitutions.
There are two solutions to this problem. First, if the contents of the array ele
ment is a number, it can be accessed using the SET /A command. For example:
1. c : \ >set X= 1 2
2. C : \ >set USERSIZE_%X%_=1 00
3. C : \>set / a RET=USERSIZE_%X%_
4. 1 00
5. C : \ >echo %RET%
6. 1 00
this technique works only for numeric values. If USERSIZE_1 2_ contained, say,
cows, then RET would be set to zero, as the SET I A assignment only assigns
numeric values, not strings.
The second, and more general method to access array elements uses the FOR
command. For example:
1. C : \ >set X=1 2
2. C : \ >for / f " delims== tokens=2 " %i i n ( ' set USERS_%X%_ ' ) d o @set RET=%i
3. C : \ >echo %RET%
4. MarkP
The FOR command sets the RET variable to the contents of the variable
USERS_1 2_. As with the previous FOR command, this command can be wrapped
in a DOSKEY macro. For example:
C : \>doskey geta=fo r / f " delims== tokens=2 " %i in ( ' set $2_$3_ ' ) do @set $1 =%i
This macro can now be used to recall any array element into any variable. For
example:
1. C : \ >set X= 1 2
2. C : \>geta RET USERS %X%
3. C : \>echo %RET%
4. MarkP
The first argument of the GETA macro is the name of the destination variable,
the second is the name of the array, and the third is the index.
This array scheme, and the macros and commands already demonstrated, is
not restricted to numeric index values. Strings can also be used as an index
value. For example: ·
This example creates a three-entry USERSIZE array. The entries are indexed with
the strings MarkP, Ka r l M and BobW.
The array scheme developed here is not limited to one-dimensional arrays.
Simply by extending the naming convention, two-dimensonal arrays can also
be created, or special index schemes used. Many of the example scripts in Part
II of this book make extensive use of arrays.
94 Part I: The Script Language
has two arguments, c : \ b i n and d : \ bin. Arguments are separated from each
other by spaces, tabs, commas, equal signs, or semi-colons. To include any of
these separator characters in an argument, enclose the argument wholly or par
tially in double quotes. This is useful when using long file names that might
contain spaces. For example:
c : \ >myscript " c : \ Prog ram Files " d : \ bin
In this example, the first argument is " c : \ P rogram File s " . Without the double
quotes, the shell would interpret the command as containing three arguments,
c : \ P rog ram, Files and d : \ bin.
Script arguments are accessed within the script using parameters (sometimes
known as formal parameters). A parameter consists of a percent sign followed
by a single digit, 0 to 9, for example, %2, %6, etc. Parameter 1 corresponds to
the first argument entered on the command line, parameter 2 corresponds to
the second, etc. Parameter 0 contains the name of the script file itself, exactly
as entered on the command line. Arguments beyond the ninth argument cannot
be accessed directly as parameters; therefore, %1 0 is not a valid parameter.
Instead, the SH I FT command is used to access additional arguments.
When a S H I FT command is executed within a script, it causes the contents of all
parameters to move "down" one index. For example, parameter 0 gets the
contents of parameter 1 , parameter 1 gets the contents of parameter 2, etc.
Parameter 9 then gets the contents of the next argument on the command line
(i.e. the tenth argument). The original contents of parameter 0 are lost. Thus,
each time a SH I FT command is executed, a new argument from the command
line is shifted into parameter 9 and one argument is lost from parameter 0.
The SH I FT command can be used with an optional tn argument, which starts
the shift process at parameter n. For example:
SH IFT / 3
exact command line text as entered. This parameter is not affected by the SH I FT
command.
Parameter Substitution
When a command is read from a script file, the shell replaces any parameters
in the command text with the text of the corresponding argument. This process
is known as parameter substitution and is similar to the variable substitution
described previously in this chapter.
Parameter substitution occurs at the same time as variable substitution.
Therefore, the same general rules that govern variable substitution also apply
to parameter substitution. For example, parameter substitution occurs before
any other parsing of the command. Therefore it is possible to pass fragments of
commands into scripts as arguments.
For example, consider a sample script named TESTl .BAT containing these
commands:
1 . echo %*
2 . copy %1 %2
The script begins by echoing all arguments, and then copies all .BAK files from
the C:\WINNT directory to the D:\BACKUP directory.
Parameters are frequently used with the I F command to validate that the com
mand syntax was correct. For example, the TEST.BAT script shown previously
fails if only one argument is supplied. To correct this, add an I F command:
1 . echo %*
2 . if {%2}== { } ( echo syntax erro r : missing argument ) ( got o : EOF )
3 . copy %1 %2
The script now checks that at least two arguments are present before proceed
ing. Otherwise, it reports an error and aborts. The I F and GOTO commands are
covered in detail in Chapter 4.
If these lines are stored in the script TEST2.BAT, then the following command
can be executed:
1 . C : \ >test2 absolutely fabulous
2. bbsolutely fbbulous
The qualifiers use the current drive and directory to fill in items that are not
explicitly specified in the parameter. For example, if the parameter %1 contains
d : \ bi n, then %-d 1 returns d : as expected. If parameter %1 contains \ bin, then
%-d 1 returns c : , assuming C: is the current drive. This means that the qualifiers
can always be relied upon to return valid information, even if this is not explic
itly present in the parameter.
Qualifiers can be combined to yield a composite result. For example, %-nx 1
returns the file name and extension from parameter 1 .
The $var : qualifier treats var as an environment variable that contains a search
path (formatted as a list of directories separated by semi-colons). The qualifier
then searches the directories for a file name that matches the specified argu
ment, and returns the fully qualified path name of the first file found. For
example, if parameter 1 were to contain the text lette r . doc:
e c h o %-$PATH : 1
Then this example searches all directories specified by the PATH variable until it
finds one that contains the file LETTER.DOC. It then echoes the full drive,
Chapter 3 : Script Parameters and Variables 97
directory and name of that file. To just return the drive and path, combine this
qualifier with the d and p qualifiers. For example:
echo %-dp$PATH : 1
The first argument contains a space in the file name, and so is quoted. The
quotes are included as part of the argument, so when the script is executed, the
COPY command appears as follows (after parameter substitution):
copy " c : \ Prog ram Files " d : \ backup
The double quotes correctly indicate the source directory to the COPY command.
Because the double quotes are passed intact as part of the argument, they con
tinue to "protect" the file name from any problems that might occur if they
were not present.
Sometimes, however, it may be necessary to strip double quotes from an argu
ment within a script. Unfortunately there is no easy way to do this that works
under all circumstances. The simplest method is to copy the parameter into a
variable and then use string substitution to delete all double quote characters.
For example:
1 . Set VAR1 =%1
2 . Echo %VAR 1 : " =%
This deletes the double quotes, but it also deletes any embedded double quote
characters, which may not be desirable. Fortunately, embedded double quotes
are rare, and using string substitution should work for almost all real-world
scripts.
Double quotes provide additional difficulties when dealing with the IF com
mand (which is described in detail in Chapter 4). For example:
if "%1 " == " c : \ t emp " goto : TEMP
98 Part I: The Script Language
This command will not work if argument 1 already contains double quotes
from the command line (for example, " c : \ t e m p " ) . In this case, after parameter
substitution, the command will be:
if " " c : \temp " == ' c : \temp " goto : TEMP
This is not legal syntax for an I F command, and the shell will report an error.
Leaving out the quotes does not help. For example:
if %1 ==c : \ temp goto : TEMP
In this case, a quoted argument will work, but now the IF command will fail if
parameter 1 is empty. In this case, after parameter substitution, the command
will be:
if ==c : \ temp goto : TEMP
Again, this is not a legal I F command. Similar problems arise with variables in
IF commands. Should they be quoted?
To solve this dilemma, observe that a parameter will never contain spaces
unless it is quoted (otherwise the shell would break the parameter into multiple
parameters without the spaces). The following guidelines can then be used to
avoid syntax errors:
• Never quote parameters in a script. As noted above, if a parameter con
tains spaces, it will already contain a set of quotes, and adding extra
quotes will cause an error. If a parameter does not contain spaces, quotes
are not needed.
• Enclose parameters used in IF commands in braces. Braces satisfy the
syntax needs of the I F command but also prevent confusion should a
parameter already contain quotes. If the parameter is empty, the braces
prevent the IF command from causing a syntax error.
• Never include quotes within the contents of a variable. A variable can
contain spaces without needing double quotes. Sometimes, it is necessary
to quote a variable name within a script. If the variable content also con
tains quotes, two sets of quotes will be included in the script, causing syn
tax errors.
• Always delete quotes when copying a parameter to a variable. Parameters
may contain quotes, but variables should not. Therefore, when copying a
parameter to a variable, always delete quotes (using string substitution).
• Quote variables in a script when needed. Variable substitutions should be
quoted if spaces introduced by the substitution would cause a syntax
error. Generally, variables are quoted unless they are part of an ECHO or
SET command. Variables should be quoted when they are used in an I F
command.
Chapter 3: Script Parameters and Variables 99
These rules are best understood by considering the following example script
fragment:
1. if {%1 }== { } goto : END
2. set SRC=\1
3. set SRC=\SRC : " =\
4. if "\SRC\ " == " c : \ t emp " goto : TEMP
5. copy " \SRC\ " %2
• Script procedures
More advanced control flow techniques are discussed here, including pro
cedures and parameter passing techniques.
• Procedure structure
This section shows how to use the various core shell features to construct
well-behaved procedures and procedure libraries.
• The I F command
This command is the fundamental command used to provide conditional
command execution, allowing scripts to alter their actions based upon
various testable conditions.
• Interactive commands
Several commands are specifically designed to allow script to interact
with the user.
• The FOR command
The FOR command is probably the single most powerful command for
script development. This section details how the power of this command
can be used in scripts.
file. Script execution terminates when the shell reaches the end of the file. This
is the default control flow used in all scripts (and in most other programming
languages) .
Script control flow can b e modified within a script file by using branches. A
branch command alters the control flow, diverting it to another location within
the current script file or another script file. The branch commands supported
by the shell are
• Jumping from one script to another by a process known as chaining.
• Executing another script by a process known as nesting.
• Jumping to another location in the script file using a GOTO command.
• Calling a procedure (subroutine) using a CALL command. The CALL com
mand is described in subsequent sections of this chapter.
Chaining Scripts
The simplest control flow process is chaining. Chaining transfers control flow
from the current script file to a new script file. The shell discards the current
script, stays in script mode, and continues script execution at the first line in
the new script file. To chain to a new script file, specify the new script file as a
command. For example:
1 . echo Now c h aining to file CLEANUP . BAT
2 . cleanup
When the CLEANUP line executes, the shell chains to the file CLEANUP.BAT (or
CLEANUP.CMD). A directory path can be specified if required, for example:
c : \ sc ript s \ cleanup
If a path is not specified, the shell searches for the script using the normal com
mand search procedure described in Chapter 2. "The Windows NT Command
Shell. "
Chaining to a new script performs a jump operation; execution o f the current
script terminates. It is not possible to return to the original script and continue
execution-when the chained script terminates, script mode terminates and the
shell returns to interactive mode.
Any number of chaining operations can be executed. For instance, SCRIPT1
can chain to SCRIPT2, which then chains to SCRIPT3, etc. A script can even
chain to itself (either directly or indirectly through a circular chain of scripts),
creating a simple loop in which the script(s) repeatedly executes.
Chapter 4: Control Flow, Procedures, and Script Nesting 103
Chained scripts acquire the current shell state (such as the current drive and
directory), but are given a new set of arguments obtained from the c ha i n com
mand. For example, assume SCRIPTl .BAT contains
1 . echo Argument 1 =%1
2 . cleanup c : \ backup
To chain to a script with all current arguments intact, use the %* parame
ter (described in Chapter 3, "Script Parameters and Variables") as the
only argument to the c h a i n command. For example:
cleanup %*
This command chains to the CLEANUP.BAT script and passes all of the
current arguments to this script.
Nesting Scripts
Although chaining enables one script to execute another, this feature is of
limited value because the shell does not return to the chaining script after the
chained script terminates; chaining is a jump operation.
Script nesting enables one script to execute another as a simple subroutine. The
nested script executes to completion, and the nesting script then continues exe
cution. Thus, script nesting enables one script to execute another as a
procedure.
Nested scripts execute using nested command shells and use the / C switch to
execute the script. For example, assume SCRIPTl.BAT contains:
1 . echo In SCR I PT1 . BAT . . .
2 . cmd / c cleanup
3. echo I n SCR I PT1 . BAT again . . .
1 04 Part I: The Script Language
The ECHO command output shows that the CLEANUP.BAT script executes as a
procedure of the SCRIPTl .BAT script.
As described in Chapter 3, it is considered good practice to execute nested
command shells indirectly using the %COMSPEC% variable. Therefore,
SCRIPTl.BAT should be re-written as:
1 . echo I n SCR IPT1 . BAT . . .
2 . %COMSPEC% / c cleanup
3. echo I n SCRIPT1 . BAT again . . .
As with chained scripts, a nested script has its own set of arguments and para
meters. Any arguments required by the nested script must be explicitly passed
to the script on the command line. For example:
%COMSPEC% / c cleanup c : \ backup d : \ backup
Recursion (either direct or indirect) can also be used with script nesting.
Recursion is a programming technique where a procedure (or script) calls itself.
Typically (as in the following DELM.BAT example) the procedure has a set of
data to process, and calls itself recursively to process a subset of that data.
Recursion is an advanced programming technique and should be used with
great care, as mis-use can cause significant problems (such as an endless recur
sion). However, there are several classic computer algorithms, such as tree sort
ing, which are most easily handled using recursion.
This example script, DELM.BAT, uses recursion to delete up to nine files, each
specified on the command line:
1 . if {%1 }== { } goto : EOF
2. del %1
3 . %COMSPEC% / c %0 %2 %3 %4 %5 %6 %7 %8 %9
C : \ >delm x y z
This causes file z to be deleted, and yet another line 3 to be executed. This
time, the line is expanded to:
cmd /c delm
106 Part I: The Script Language
This nested execution is passed no arguments: All the arguments to the original
shell have now been consumed. When this nested script executes, line 1 finally
comes into effect. Parameter %1 is empty, and the GOTO statement (covered in the
following section) jumps to the end of the file.
The GOTO terminates the innermost command shell. The previous shell then con
tinues execution, and because it is at the end of the script file, it also termi
nates. This termination process continues for all earlier nested command shells,
and this cascade of shell termination completes when the original script file
terminates.
When a script uses recursion, execution of the current copy of the script
file is suspended, and another command shell is created to begin execu
tion of the same script file. If the recursion continues indefinitely, many
additional command shells are invoked. Eventually, Windows NT
exhausts all available resources, and the script fails.
Labels must be placed on a separate line from other commands. They cannot
be placed within a compound command, even if the compound command is
broken across multiple lines by parentheses. Spaces are allowed before the
colon character and between the colon and the label text. Labels in this book
are shown in uppercase, but they are not case sensitive.
Labels can contain letters, digits, and the underscore character. Other charac
ters are allowed, but should be avoided, as they can cause difficulties when
labels are used with GOTO and CAL L commands. Labels can be very long-in
excess of 50 characters.
Chapter 4: Control Flow, Procedures, and Script Nesting 107
When a GOTO command executes, script execution continues at the line follow
ing the target label. The label can be either before the GOTO command (creating
a loop) or after the GOTO command (jumping ahead in the script).
In MS-DOS and earlier versions of Windows NT, labels and the GOTO command
were used extensively to describe the control flow logic of scripts. However,
the compound command statements make many such uses of the GOTO com
mand obsolete. For example, in MS-DOS this script code was frequently used
to check that a required argument was present:
1 . if not "%1 " == " " goto ARG1 0K
2 . echo error : missing argument
3 . goto exit
4 . : ARG1 0K
5.
6.
7 . : EXIT
This single line replaces all the lines shown in the previous example, and is far
easier to understand. If desired, the line can be written as a multi-line
command:
1 . if {%1 }=={ } (
2. echo error : missing argument
3. goto : EOF
4.
Both the single line and multi-line versions have the same effect. The choice of
which to use should be based on style and clarity of meaning.
The DELM.BAT script shown earlier can be re-written using the GOTO com
mand. Written this way, DELM2.BAT does not use recursion, which makes it
108 Part I: The Script Language
This script loops repeatedly between the : NEXT_FILE label in line 2 and the GOTO
: NEXT_FI L E command in line 7. The I F command in line 3 terminates the script
when there are no more arguments to process (or if none were specified on the
command line). Line 4 deletes the first file specified, while the SH I FT command
shifts down the arguments. Using SH I FT like this lets the loop process each
argument one by one, by shifting each argument into parameter % 1 . Eventually,
all arguments are processed and the I F command terminates the loop.
This version of the DELM script has also been enhanced by adding a file counter
and displaying the count of files deleted at the end of the script.
transfers control to the end of the file. Because script file processing terminates
at the end of the file, this command is interpreted as an end script command.
When a GOTO : EOF command executes in a script procedure, it is interpreted as
a return command.
Script Procedures
Although much can be accomplished by using the simple control flow con
structs previously described, virtually all non-trivial scripts can use procedures
to improve robustness and reduce maintenance overhead. The virtues of using
procedural elements in programs are well known, and include code re
useability, compartmentalization (hiding implementation details within proce
dures), and structured design (breaking a large problem into a set of smaller
ones) . All of these virtues can be realized in scripts by using script procedures.
part of a script. When the called portion of the script terminates, execution of
the current script resumes at the next command after the CALL command.
Although the CALL command is similar to the script-nesting feature already
described, it is superior to it for two reasons:
• The CALL command can execute a portion of the current script as a proce
dure, whereas script nesting only nests entire script files.
• The current shell executes the procedure.
Because the CALL command executes the procedure within the current shell, the
procedure shares the environment of the caller, and can therefore modify script
variables. In contrast, a nested script inherits the shell environment, and cannot
modify the caller's variables.
To execute another script file as a procedure (an inter-file procedure call),
follow the CALL command with the name of the script. For example:
call cleanup
If a path is not specified, the shell searches for the script using the normal com
mand search procedure described in Chapter 2.
To execute a part of the current script file as a procedure (an intra-file proce
dure call), follow the CALL command with a colon and a label. For example:
call : SUB1
Unlike the GOTO command, the intra-file CALL command requires the colon char
acter before the script label, in order to distinguish an inter-file from an intra
file call.
Regardless of the location of the procedure (a new script file or a label in the
current script), the command shell executes the specified procedure until the
procedure reaches the end of the script file. Execution then resumes at the com
mand following the CALL command. This can be either the next line or the next
command on the same line if the command is a compound command.
Procedure execution ends when the shell reaches the end of the script file con
taining the procedure. The GOTO : EOF command is typically used to end the pro
cedure and return to the calling script. For example:
1. echo Starting . . .
2. call : SUB1
3. echo Ending . . .
4. goto : EOF
5.
110 Part I : The Script Language
6.
7 . : SUB1
8. echo I n procedure SUB1
9 . goto : EOF
The procedure SUB1 is bracketed by the procedure label at the start and a GOTO
: EOF command at the end. If required, procedures can contain additional GOTO
: EOF commands. The main body of the script also contains a GOTO : EOF com
mand at line 4. Without this command script execution would continue from
line 3 and " fall through" into the SUB1 procedure, accidentally executing the
procedure a second time.
Place procedures in a script after the main body of the script. Place a GOTO
: EOF command before the script label (as well as at the end of the proce
dure), so that if a previous procedure accidentally falls through to the
procedure, it does not execute by mistake. For example:
3.
Procedure Nesting
Procedure calls can be nested; procedures can call other procedures. Any com
bination of intra-file and inter-file procedure calls is allowed, but all intra-file
procedure calls are relative to the current script file. For example, if
SCRIPTl .BAT calls SCRIPT2.BAT using an inter-file CALL command, then any
nested intra-file CALL commands within SCRIPT2.BAT will call procedures
within that file (SCRIPT2.BAT) .
The nesting of procedures is limited by command shell stack space. Typically,
procedure calls can be nested several hundred deep, far more than is likely ever
to be encountered by typical scripts.
Chapter 4: Control Flow, Procedures, and Script Nesting 111
This procedure alters the current directory. However, by bracketing the proce
dure within a PUSHD/POPD command pair, changes to the current directory are
made local to the procedure. The procedure is "well behaved" and preserves
the current directory. This kind of defensive programming avoids unwanted
procedure side effects and leads to more robust scripts.
As a convenience, the PUSHD command can switch to a specified drive and direc
tory. For example, the previous example can be written as
1. : SUB1
2. pushd \ backup
3.
4.
5. po pd
6. goto : EOF
Other uses of the PUSHD and POPD commands are described in Part III, "Scripting
Command Reference. "
p u s h d \ \ Da taSe r v e r \ Sh a re 1 \ MyDi r e c t o ry
When used like this, the PUSHD command automatically creates a tempo
rary drive letter mapping for the UNC name. The first free drive letter is
1 12 Part I: The Script Language
used, starting at Z: and working down the alphabet. Once mapped, the
PUSHD command then makes this drive and directory the current drive and
directory.
The POPD command automatically undoes any UNC drive mappings when
it executes. Using PUSHD/POPD to map UNC names is particularly useful in
scripts that are scheduled via the AT command. As Chapter 2 explained,
these scripts cannot rely on user-defined network drive mappings.
Procedures can also alter variables in the current environment. These changes
are global in scope, and so are still in effect after the procedure returns. To
limit the scope of environment variable changes, use the SETLOCAL and ENDLOCAL
commands to bracket the procedure. These commands are described in Chap
ter 3. For example:
1. : SUB1
2. setlocal
3.
4.
5. endlocal
6. goto : EOF
When either PUSHD/POPD or SETLOCALIENDLOCAL (or both) are used, take care to
exit the procedure correctly. For example, the following procedure contains a
significant error:
1. : SUB2
2. setlocal
3.
4.
5. if {%1 }== { } goto : EOF
6.
7. endlocal
8. goto : EOF
This works, but if PUSH/POPD brackets are also used, they must also be added.
Maintenance becomes difficult if the procedure contains many such I F
commands.
Chapter 4: Control Flow, Procedures, and Script Nesting 1 13
Use the %* parameter to pass all current arguments to a procedure. For example:
call : SUB1 %*
back from a procedure to the caller. This is only a convention, however, and
procedures are free to use any other return mechanism they choose, as long as
both the caller and callee agree upon the details.
Chapter 3 also described how to return a value correctly when using the
SETLOCAL and ENDLOCAL commands to enforce local variable scope. The RET vari
able can " tunnel" across the local scope by assigning the variable to itself on
the same line as the ENDLOCAL command. For example:
endlocal & set RET=%RET%
Procedure Structure
The CALL and GOTO : EOF commands provide the core commands to enable
scripts to be structured. They enable the work of a script to be broken into log
ically distinct blocks of code, each of which performs a particular task. This
section provides additional information on various structuring techniques.
The first three lines of this skeleton are the standard lines introduced in Chap
ter 1 . Line 8 deletes the RET variable, so that the default return value from this
script is nothing. Obviously, this is only significant if the script executes
through an inter-file CALL, but it is good practice to structure all scripts so that
they include a return value.
Line 8 also creates a local scope and state using the SETLOCAL and PUSHD com
mands, so that the MAI N procedure (and any other in the script) is free to alter
state and variables without creating unexpected side effects.
Line 9 saves the name of the script file in the variable SCRI PTNAME. All the script
logic is in the MAI N procedure, but inside this procedure the parameter %0 value
is : MAIN, not the name of the script file. Saving the script file name in
SCR I PTNAME allows the MAI N procedure (or any other) to reference this informa
tion if necessary.
Line 1 0 sets up script tracing. The shell has no built-in tracing support, but line
10 provides a simple trace facility. If the DEBUG variable is set to 1 before the
script executes, tracing is enabled. Otherwise, tracing is disabled. To enable
tracing, the TRACE variable is set to e c h o . To disable tracing, the TRACE variable is
set to rem.
To generate trace output, include a line containing %TRACE% and any trace text.
For example:
%TRACE% This is t race output . , .
If tracing is enabled, %TRACE% is replaced by echo, and so the trace text is dis
played. If tracing is disabled, %TRACE% is replaced by r e m , and so the trace text is
ignored. An example of tracing can be seen at the start of the MAI N procedure.
For robustness, this line checks the TRACE variable to verify that it is defined
before it executes.
Line 1 1 calls the MAI N procedure. All command line arguments are passed
directly to the MAI N procedure via the %* parameters. The MAI N procedure then
executes the script logic.
When the MAI N procedure returns in line 12, the local scope and state are delet
ed, and the return value in RET (if any) is tunneled back out of the local scope.
Finally, line 13 exits the script.
116 Part I : The Script Language
This skeleton places a safety GOTO : EOF command before the procedure start. It
uses SETLOCAL and ENDLOCAL commands to give all variables local scope, and uses
PUSH and POPD commands to make state changes local. The : EXI T_XYZ label pro
vides a procedure exit label for use within the procedure body. Finally, it
returns a value in the RET variable, which is cleared at the start of the proce
dure. If desired, these commands can be combined into compound commands
as follows:
01 . .
02 . .
03 . REM XYZ procedure
04 . Goto : EOF
05 . : XYZ
06 . setlocal & pushd & set RET=
07 . ( body of p rocedure here )
08 .
09 .
10. : EXIT_XYZ
11. popd & endlocal & set RET=%RET%
12. goto : EOF
Script Libraries
The CALL command can either call a procedure within the current script (an
intra-file call) or call another script file as a procedure (an inter-file call).
Sometimes it is necessary to call an individual script procedure within another
script file, i.e., perform an intra-file call into another script file. This is called
an indirect CALL command.
Chapter 4: Control Flow, Procedures, and Script Nesting 117
The most typical use of indirect CALL commands is accessing script libraries.
Script libraries contain sets of general-purpose procedures that can be used by
other scripts. Although a script library could be developed using a series of
individual files (one procedure per file), it is more efficient if these scripts can
be placed within a single script file.
The shell language does not support indirect CALL commands directly, but these
commands can be quite easily simulated, allowing script libraries to be built
and deployed. The scheme shown here is thus a convention: Other similar con
ventions can be developed if required.
A script library using this convention should follow these rules:
• To distinguish a script library from a regular script file, use a leading
underscore in the file name, for example _MTPLIB.BAT. This helps to
separate script libraries from regular scripts in directory listings.
• If it is executed without any command arguments, the script library
should echo a description and version number, and then exit. The library
can then be invoked from the command line to check version informa
tion, etc.
• Provide an I N i r procedure within all script libraries. Any script that
wishes to use the library must call the I N I T procedure before calling any
other library procedures. This allows the library to initialize itself before
any other procedures are called.
• Provide a dispatch function at the start of the script library to handle
indirect CALL commands. This is described below.
• To call a procedure in the library, use an inter-file CALL command and
specify the name of the procedure as the first argument. Procedure argu
ments then follow the procedure name.
Following the last rule described above, the procedure KILLALL in the script
_pROCLIB.BAT can be called by executing:
call _proclib : KI LLALL arg1 arg2
This indirect call executes the procedure KI LLALL in the script library
_PROCLIB.BAT, passing the procedure two arguments, arg1 and arg2.
A skeleton script library, _LIBSKEL.BAT, is shown in the following example:
01 . @echo OFF
02 . @if not " %ECH09ts " == ' " echo %ECHO%
03 . @if not " %0S% " = = " Windows_NT " goto DOSEXIT
04 . rem $Workfile : MODEL1 . BAT $ $Revision : 4 $ $Date : 7/ 01 / 97 3 : 27p $
05 . rem $Archive : / SrcSaf e / Proto / MODEL1 . BAT $
06 .
118 Part I : The Script Language
Line 8 handles the display of library version information if the library executes
with no arguments. If one or more arguments have been supplied, the library
dispatches to the appropriate procedure. The dispatch code consists of these
three lines:
1 . set _PROC=%1
2 . s h ift / 1
3 . goto %_PROC%
The first line saves the first argument (the name of the procedure to call) in the
variable _PROC. The second line shifts all arguments starting at argument 1 . This
eliminates the first argument from the argument list to be used later by the pro
cedure. Finally, the GOTO command jumps to whatever label is named in the
_PROC variable. This indirect GOTO is the key to the indirect CALL convention.
When the library executes, by an inter-file CALL, the first argument is the name
of the procedure to call. Hence, %1 contains the procedure name, and the com
mand GOTO %_PROC% jumps to the start of this procedure. When the procedure
executes a GOTO : EOF command, the inter-file CALL returns.
The SHI FT command in line 15 ensures that arguments accessed in individual
procedures are accessed correctly. The first procedure argument actually comes
from the second argument to the original indirect CALL command (the first is
Chapter 4: Control Flow, Procedures, and Script Nesting 119
the procedure name). The SHI FT command hides this, and allows the procedure
to access the first argument as %1 etc.
Notice that if an attempt is made to call a procedure which does not exist, the
GOTO command in line 1 6 will fail with an error, and script execution will halt.
The I F Command
The IF command provides conditional script command execution. The general
syntax of an IF command is:
I F condi tion conunand
The I F command first evaluates the condi tion. If the condition is true, the
command executes. If the condition is false, the command does not execute and
control flow continues to the next statement. The command can be a compound
command in parentheses, which enables several commands to execute, depend
ing upon the result of the conditional test.
The IF command can include an ELSE clause. The syntax of this I F command is:
IF condi tion ( true - conunand ) ELSE ( false - conunand )
Again, the I F command first evaluates the condi tion. If the condition is true,
then the true - command executes. If the condition is false, the false - command exe
cutes. Both the true - command and false - command can be compound commands,
and both require parentheses.
Simple I F Commands
The following IF commands provide ways to test a variety of conditions,
including command exit codes, string values, and variable definitions.
The error level test evaluates to true if the previous command returned an exit
code with a value greater than or equal to l e vel . Commands generally return
an exit code of 0 is they are successful and non-zero if they encounter an error.
For example:
1 . dir / *
2 . if erro rlevel 1 echo I nvalid DIR command
If the arguments to the DIR command are invalid (as in this case), the I F com
mand displays the error message.
120 Part I: The Script Language
The NOT clause inverts the test performed by the IF ERRORLEVEL command: The
command executes if the exit code of the previous command was less than l evel .
The test evaluates to true if the command extension version is greater than or
equal to version. In this case, the command executes. For example:
if cmdextversion 2 set DI R=\-q 1
The I F D E F I N E D Command
The I F DEFI NED command tests for the existence of a variable. The syntax of
the command is:
IF [ NOT ] DEFINED var - name command
If the variable specified by var - name is defined, the command executes. Do not
bracket the variable name in percent signs. For example:
1. set / a COUNT=0
2. : LOOP
3. set / a COUNT+=1
4. if defined ARRAY_\X\_ goto : LOOP
5. set / a COUNT - = 1
This example counts the number of entries in the array named ARRAY, assuming
the array is not sparsely populated; i.e., the script counts up until the first
undefined array entry is reached.
The NOT clause inverts the test performed by the IF DEFINED command: the
command executes if the specified variable is not defined.
The two strings string 1 and string2 are compared. If they are identical (both
strings are the same length, and all characters match), the command executes.
Chapter 4: Control Flow, Procedures, and Script Nesting 121
Use the NOT clause to execute the command if the strings are different. The strings
to compare are separated by two equal signs.
The strings can have leading and trailing spaces, which are not included in the
comparison. For example, all these IF commands execute the ECHO command:
1 . if a==a echo Idential
2 . if a ==a echo Identical
3 . if a == a echo Identical
To include leading and trailing space in the comparison, enclose both strings in
double quotes. For example:
if " a " == " a " echo Identical
When comparing variables, always place both strings in double quotes. If the
double quotes are not included, problems can arise. For example:
if %DEBUG%==1 echo Debug enabled
If the DEBUG variable is not defined, after variable substitution this command is:
if ==1 Debug enabled
This generates a syntax error. Placing double quotes around both strings avoids
this problem.
A similar problem arises when comparing parameter values. These may be
empty, or may already contain double quotes. Therefore, always enclose para
meters within braces when they are used in an IF command. For example:
if {%1 } == { } echo Missing Parameter !
For additional information on the use of double quotes in variables and para
meters, see the discussion of double quotes at the end of Chapter 3 .
The / r switch in a string-compare I F compares the two strings using a case
insensitive comparison. In this case, the strings " abc " and " ABC " are considered
identical.
One common use of the string-compare IF command is to process all script
arguments sequentially. For example:
1. : NEXT_ARG
2. if {%1 } == { } goto : DONE
3. call : PROCESS_ARG %1
4. s hift / 1
5. goto : NEXT_ARG
6. : DONE
122 Part I: The Script Language
This script code calls the PROCESS_ARG procedure for each script argument. The
code loops until the parameter %1 is empty. Each time the loop executes, the
SH I FT command moves the next argument into %1 until no more arguments are
available. The loop then terminates.
Advanced I F Commands
The following IF commands provide ways to test for the existence of files and
directories and compare values numerically.
The I F E X I ST Command
The I F EXIST command tests to see if a file or directory exists. The syntax of
the command is:
IF [ NOT ] EXIST fil e command
A drive letter and directory path can be specified along with the file name. If
these items are not supplied, the current drive and directory are used.
The NOT clause inverts the test performed by the I F EXIST command: The
command executes if the specified file does not exist.
The I F EXIST command can be used with wild card file names. For example:
if exist * . txt echo dir * . txt
When used with a wild card, the I F EXIST condition is true if at least one file
that matches the wild card exists in the current (or specified) directory.
The command shell has more flexible wild card features than those found
in MS-D OS. Asterisks may appear anywhere within a wild card pattern.
For example, * s . * locates all files with names ending in "s " and D*s . txt
locates all . TXT files with names starting with "D " and ending in "s. "
This example will execute the ECHO command if c : \d os is either a file or a direc
tory. To unambiguously distinguish between a file and directory using I F EXIST,
check for the presence of a file named " . " . All directories contain a directory
named " . " . For example:
if exist c : \dos \ . echo Directory c : \ dos exists AND is a directory
Chapter 4: Control Flow, Procedures, and Script Nesting 123
This IF command only executes the ECHO command if c : \dos exists, and it is a
directory.
If the file name or directory name contains spaces or is a variable, enclose the
name in double quotes. For example:
if exist " c : \ Program Files \ * . com " echo P rograms found
The relational IF command compares val ue 1 and value2 using the relop opera
tor. If the comparison is true, the command executes. Table 4.1 lists the available
relational operators.
If both value 1 and value2 are numeric values, then the comparison is performed
numerically. Otherwise, the comparison is performed lexically, using the ANSI
collating sequence (i.e., the Windows character set).
For example:
1 . if 256 EQU 0x1 00 echo Nume rically equal
2. if " 256 " EQU " 0x 1 00 " echo Lexically equal
The first IF command evaluates to true because the two values are numerically
equal ( OxlOO hexadecimal is 256 decimal). The second I F command evaluates
to false because the string values are lexically different.
124 Part I: The Script Language
When comparing strings lexically, a string is " less than" another string if it is
shorter in length or the first non-identical character in the two strings has a
numerically smaller ANSI code in the first string.
The opening parenthesis that begins the multi-line command must appear on
the same line as the I F command. The closing parenthesis can appear on a line
by itself or at the end of the last command. Indenting the commands as shown
in the prior example is optional but does improve the readability of the script,
as it helps to highlight the control flow through the script.
Multi-line commands can also be used with the ELSE clause of an IF command.
For example:
1 . if defined USERNAME (
2. echo A user is logged - on
3. goto : LOGGEDON
4. else (
5. echo A user is not logged - on
6. goto : NOTLOGGEDON
7.
The first closing parenthesis, the E LSE clause, and the opening parenthesis of
the ELSE clause must appear together on the same line. As in the previous
example, indenting is used to improve readability.
The command executed by an I F command can be any valid shell command,
including another I F command. For example:
1 . if not " %PROCESSOR_ARCH ITECTURE% ' == " x86 " (
2. if not " %PROCESSOR_ARCHITECTURE% ' == " MI P S "
3. echo Intel o r MIPS compatible CPU required
4. goto : EOF
5.
6.
Similarly, each nested I F command can have an ELSE clause. Care should be
taken to correctly match E LSE clauses to I F commands: Each ELSE clause binds
to the most deeply nested I F command. Statements such as the case (or switch)
Chapter 4: Control Flow, Procedures, and Script Nesting 125
Interactive Commands
There are several commands that are specifically designed to enable a script to
interact with the user. These are:
• The PAUSE command, which waits for a key press before continuing script
execution.
• The T I MEOUT [ RKJ command, which waits for a key press for a specified
interval.
• The SLEEP [ RKJ command, which pauses script execution for a specified
interval.
• The CHO ICE [ RKJ command, which gets a single key stroke.
PAUSE
The simplest o f these commands is PAUSE, which i s typically used to pause exe
cution so that command output can be viewed. The PAUSE command displays
the message:
Press any key to continue . . .
Script execution pauses until a key is pressed, after which it continues nor
mally. Pressing Ctrl+C or Ctrl+Break terminates script execution (after
confirmation).
T I MEOUT [ R K ]
The T IMEOUT [ R K J command enhances the PAUSE command by adding a timeout
feature. Specify the timeout, in seconds, with the T IMEOUT command. For
example:
C : \ >timeout 5
This command pauses until either a key is pressed or the 5-second timeout
period expires. During the timeout, the command displays a countdown of the
time remaining.
126 Part I: The Script Language
SLEEP [ RK ]
The SLEEP [ R K J command pauses script execution for a specified number of
seconds. For example:
C: \>sleep 5
The SLEEP command is not interactive, but it is frequently used to delay script
execution so that results can be displayed, or to "pace" a script so that it does
not execute too quickly. While a SLEEP command executes, the thread executing
the script is suspended, and therefore does not consume CPU resources.
The first line of MASTER.BAT deletes the file lockfile if it exists. Line 2 starts
the slave script in a new window. Both scripts are now running at the same
time. Line 3 indicates that the MASTER script can now perform any additional
processing desired. Line 4 marks the start of a wait loop. The MASTER script
now spins in the loop from lines 4 to 6 until the file lockfile exists.
The SLEEP command in line 5 is not technically necessary-the loop works
without it. But it does make the script thread yield the CPU for 1 second on
each loop pass. This makes the loop well behaved in a multi-threaded OS like
Windows NT.
The SLAVE script performs any desired processing (in this case, just a PAUSE com
mand) and then indicates completion by creating the loc k f i l e file in line 3. The
contents of the lock file are not important-merely that it is created. This trig
gers the MASTER script to drop out of its wait loop.
Chapter 4: Control Flow, Procedures, and Script Nesting 127
The flaw in this scheme is that the MASTER script waits forever for the
SLAVE script. If something goes wrong in the SLAVE script, the MASTER
script may never terminate. Adding a time-out check to the wait loop can solve
this. This example procedure encapsulates a generic "wait for file" loop that
incorporates this timeout:
01 . rem FI LEWAIT procedure
02 . rem Wait for a file to exist , wit h a timeout
03 . rem %1 =Name of f ile to check
04 . rem %2=Timeout period , in seconds
05 . rem Returns t imeout pe riod ( second s ) or -1 if timeout occur red
06 . : FI LEWAIT
07 . setlocal
08 . set / a RET=0
09 . : FILEWAIT_LOOP
10. sleep 1
11 . set / a RET+=1
12. if %RET% LSS %2 if not exist %1 goto : FI LEWAIT_LOOP
13. if %RET% GEO %2 set RET= - 1
14. endlocal & set RET=%RET%
15. goto : EOF
CHO I CE
The CHOICE [ R K J command waits for the user to type one key from a specified
set of choices, and then returns an exit code indicating which key was pressed.
This exit code can then be used with the I F ERRORLEVEL command or
%ERRORLEVEL% variable to control script execution.
The basic CHO I CE command displays a prompt and waits for a Y or N key to be
pressed before continuing:
C : \ >choice Do you wish to continue
Do you wish to continue [ Y , N ] ?
Either upper o r lower case keys are accepted, unless the /S switch i s used,
which treats upper and lower case letters as distinct.
The default CHO I CE command displays the list of possible keystrokes in brack
ets, followed by a question mark after the prompt. The / N switch suppresses
this. For example:
C : \ >choice / n Do you wish to continue :
Do you wish to continu e :
128 Part I: The Script Language
The / C switch specifies allowed keyboard input choices (the default is Y or N).
For example:
C : \ >choice / c : 1 23 Enter adapter card type
Enter adapt e r card type [ 1 , 2 , 3 ] ?
This command accepts the keys 1 , 2 or 3 only. Letters specified as choices with
the / C switch are not case sensitive, unless the /S switch is used.
Use the /T switch to specify a timeout for the CHOICE command. Follow the
switch with a default key and the timeout period (in seconds). For example:
C : \ >choice / c : 1 23 / t : 2 , 30 Enter adapt e r card type
Enter adapter card type [ 1 , 2 , 3 ] ?
This command automatically enters the " 2 " key a s the choice after 30 seconds.
The CHOICE command returns the position of the chosen key as an exit code.
The exit code is the index of the chosen key in the list of possible keys. For
example, if the switch / C : ABF is used, pressing A returns an exit code of 1 , B
returns an exit code of 2, and F returns an exit code of 3. The default choices
(Y or N) returns 1 for Y and 2 for N.
The exit code is typically used in an IF ERRORLEVEL command to branch based
on the choice made. For example:
1 . choice Do you want to continue
2. if e rrorlevel 2 goto : EOF
The IF ERRORLEVEL command evaluates to true if the exit code (error level) is
greater than or equal to the specified value. Therefore, this script code does not
work as expected:
1. choice / c : SPX Enter n etwor k card type
2. if errorlevel 1 goto : CARD_S
3. if errorlevel 2 goto : CARD_P
4. if erro rlevel 3 goto : CARD_X
The first I F command always evaluates as true, because the exit code from the
CHOICE command ( 1 , 2 or 3 ) is always greater than or equal to 1 . Therefore the
GOTO : CARD_S command always executes, presumably not what was desired.
This problem is easily fixed by testing for the higher numbered choices first.
Alternatively, use the %ERRORLEVEL% variable and make exact IF tests. For
example:
1. choice / c : SPX Enter n etwork card type
2. if \ERRORLEVEL\ EQU 1 goto : CARD_S
3. if \ERRORLEVEL\ EQU 3 goto : CARD_X
4. if \ERRORLEVEL\ EQU 2 goto : CARD_P
Chapter 4: Control Flow, Procedures, and Script Nesting 129
The I F . . . Eau test performs an exact equality test, and so the GOTO commands
execute correctly regardless of the order of the tests.
Another more compact method of branching on the result of a CHOICE com
mand uses carefully constructed label names. For example:
1 . choice / c : SPX Enter network card type
2 . goto : CARD_%ERRORLEVEL%
This script code jumps to the label CARD_1 if the choice was s, CARD_2 if the
choice was P or CARD_3 if the choice was x. This method is particularly useful if
a large number of choices is possible.
The version of the CHOICE command in the Windows NT 4.0 Resource Kit
supplement 2 has a bug. After executing a CHOICE command, console echo
for all line-oriented commands is disabled. To avoid this bug, execute all
CHOICE commands within a nested command shell. For example, replace
this:
choice / n Continue?
With this:
The exit code of the CHOICE command is correctly passed back from the
nested command shell, and console input echo is not disabled in subse
quent commands.
COPY
The shell does not offer a command for reading lines of console input.
However, the COPY command can be used for this purpose, by reading input
from the console into a temporary file. For example:
1 . echo Enter file name , followed by Ct rl+Z :
2 . copy con filename . tmp
The COPY command stops reading console input when an end-of-file character
(Ctrl+Z) is entered. The temporary file contains the text entered at the key
board. Typically, this text is then parsed by the FOR command (described in the
next section). For example:
for / f " delims=- " %i in ( f ilename . tmp) do set F I LENAME=%i
130 Part I : The Script Language
The i terator controls the iteration process. For each step of the iteration, the
specified command executes once. The command can be a compound command,
multi-line command, or even a procedure call, allowing multiple commands to
be executed at each iteration step.
The i terator typically specifies one or more iteration variables. Iteration vari
ables are similar to regular variables, but they only exist within the iteration. In
interactive mode, iteration variables are specified using a percent sign and a
single letter, for example, %! . Within a script, specify the iteration variable by
using two percent characters, for example, %%I .
Unlike regular environment variables, iteration variables are case sensitive: %n
and %N are different variables. When the iteration command executes, references
to iteration variables are replaced with iterator values.
Items that can be iterated by a FOR command include files, directories, numeric
ranges, and text files.
The %var is the iterator variable. The files to iterate are specified by s e t, which
is a file name or wild card file name. The FOR command iterates the current
(or specified) directory and executes the command for each matching file. For
example:
C : \ >for %I in ( * . bat ) do echo %I
C : \ >echo test . bat
test . bat
C : \ >echo master . bat
mast e r . bat
C : \ >echo slave . bat
slave . bat
This FOR command iterates all .BAT files in the current directory, and executes
the ECHO command for each file. Within the ECHO command, the iterator variable
%I is replaced with the name of the file. Notice that the FOR command echoes
Chapter 4: Control Flow, Procedures, and Script Nesting 131
By default, the current directory is scanned for matching files. To scan another
directory, specify it as part of the set. For example:
C : \ >for \I in ( c : \ d o s \ disk* . com ) do @echo \I
c : \ do s \ d is kcopy . com
c : \ do s \ diskcomp . com
In this example, the -n qualifier expands only the file name from the \I
variable.
More than one file name is allowed in set. Separate each file name with a
space, for example:
C : \ >for \I in ( * . com * . exe ) do @echo \I
This example displays all .COM and .EXE files in the current directory. Since
the space character separates file names, enclose a file name with embedded
spaces in double quotes. For example:
C : \ >for \I in ( " c : \ P rog ram Files \ * , * " ) do @echo \I
The operation of the directory iterator command is identical to the file iterator,
except that the command executes for each directory that matches the file name
set. For example:
C : \ >for / d \I in ( c : \winn t \ system * ) do @echo \I
c : \ winnt \ system
c : \winnt \ system32
132 Part I: The Script Language
As with all shell commands, the first operation performed on a FOR com
mand is environment variable substitution. This occurs before the FOR
command executes, and has certain consequences. For example, this com
mand does not work as expected:
To work around this problem, use the FOR command to call a procedure
and execute the SET command in the procedure. For example:
4 . set PATH=%PATH% ; %1
5 . goto : EOF
This solution works because the shell rescans the SET command in the
procedure at each iteration, thus allowing the PATH variable to correctly
accumulate.
The file and directory FOR commands can be combined. For example:
C : \ >f o r / d %I in ( c : \winnt \ * ) do @fo r %J in ( " %I \ * . ttf " ) do @echo %J
The first FOR command iterates all sub-directories in the C:\WINNT directory.
The second FOR command iterates all . TTF files in each of these directories.
Double quotes are used around the second FOR command s e t in case any of the
iterated directory names contain spaces. Notice the use of the @ prefix to pre
vent the ECHO command from being displayed.
The previous example iterated all files in a set of sub-directories, but this
search is only one layer deep. Files in sub-directories of sub-directories are not
iterated. The tree-iteration FOR command provides a full directory tree iteration.
The syntax of this FOR command is:
FOR / R [path ] %var IN ( s e t ) DO command
Chapter 4: Control Flow, Procedures, and Script Nesting 133
Follow the / R switch with an optional drive and directory path. This FOR com
mand walks the directory tree specified by path, and executes the FOR iteration
in each directory. For example:
C : \ >for / r c : \ %I in ( * . bat * . cmd ) do @echo %I
This example displays the full path name of all .BAT and .CMD files found
anywhere on drive C:.
If the /R switch is not followed by a drive or path, the current drive and direc
tory are assumed. If the set is * . *, then all files in all directories of the speci
fied tree are iterated. If the set is a single period, then the special directory
name " . " in each directory is iterated. For example:
C : \ >for / r c : \winnt \ system32 %I in ( . ) do @echo %I
c : \winnt\ system32 \ .
c : \winnt \ system32 \config \ .
c : \winnt \ system32 \ d rive r s \ .
Etc .
The / R and / D switches can be combined. In this case, the FOR command walks
the specified directory tree, and then iterates matching directories in each direc
tory. For example:
C : \ >for / r c : \winnt / d %I in ( system* ) do @echo %I
c: \winnt\ system
c : \winnt\ syst em32
The values s tart, s tep and end are decimal integers which control the iteration.
The iterator variable var is initialized to s tart, and then incremented by s tep
until the value of the variable is greater than end. The command executes for each
value of the iterator variable. For example:
C : \ >for /1 %I in ( 1 , 1 , 5 ) do @echo %I
1
2
3
4
5
Iteration terminates when the value in the iteration variable is greater than the
end value (6, in the previous example}. This test is made before the iteration
134 Part I: The Script Language
command executes. Therefore, if s tart is greater than end, the command is not exe
cuted at all, and if start is equal to end, the command executes once.
The s tep value can be negative. In this case, the iterator variable decreases in
value with each step, and the FOR command ends when the variable value is less
than the end value. If start is less than end, the command is not executed at all.
For example:
C : \ >f o r / 1 %I in ( 5 , - 1 , 3 ) do @ech o %I
5
4
3
The text to parse is specified by source, which can be one of the following:
• A set of one or more text file names, separated by spaces. Wild card file
names are not allowed. The text from each file is read, line by line, and
parsed. The command executes for each line of text in the source files.
• A string enclosed in double quotes. The string is parsed and the command
executed once with the parse results. The string can contain environment
variables, which are substituted before parsing occurs.
• A command enclosed in single quotes. The source command executes,
and all its command output is captured by the FOR command (it is not dis
played). This command output is then parsed, line by line, and the com
mand executed for each line of output.
Each iteration of the text parser FOR command processes a single line of text
from the specified source. Blank lines are skipped by the FOR command; i.e. the
iterator command is not executed for these lines. Non-blank lines are first parsed
into individual tokens. A token is an arbitrary block of text delimited by spe
cial delimiter characters within the line. These tokens are then assigned to one
or more iterator variables, and the iterator command is then executed using the
values of these iterator variables.
To parse a line into tokens, the line is scanned for special delimiter characters.
The delimiters define how the line is broken into tokens; the default delimiters
Chapter 4: Control Flow, Procedures, and Script Nesting 135
are space and tab, though others can be specified. For example, this source line
contains three tokens:
one two t h ree
Tokens are numbered, starting at 1 for the left-most token on the line. Once
the line is broken into tokens, the tokens are assigned to iterator variables. By
default, only the first token is assigned to a variable; all others are discarded.
After iterator variable assignment is complete, the iterator command executes.
For example, assume the text file USERS.TXT contains:
TimHill Admin 400
JohnDoe User 500
Ka renVache User 600
The text parser FOR command has one limitation, which seems to be an
oversight by the Windows NT command shell designers. The text parser
FOR command cannot directly parse the contents of a file if the file name
contains one or more spaces. For example:
C : \ >for / f %I in ( My Document . txt ) do @echo %I
This FOR command does not work because the FOR command interprets
the file set as containing two files: My and Document . txt. Unfortunately,
this cannot be corrected by using double quotes. For example, the follow
ing does not work:
C : \>for / f %I in ( " My Document . txt " ) do @echo %I
The shell interprets this command as a request to parse the literal text My
Document . t x t, rather that the contents of a file by this name. This is one of
the few places in the command shell where a file name containing spaces
cannot be correctly processed if enclosed in double quotes.
The work-around for this problem is to parse the text file indirectly. Use
the TYP E command to output the file, and then capture the output of that
command. For example:
C : \ >for / f %I in ( ' type " My Document . t xt " ' ) do @echo %I
136 Part I: The Script Language
The EOL option specifies an optional end-of-line delimiter character. The parser
ignores all text on each line beyond this character. This character therefore acts
as a "comment" delimiter character, allowing arbitrary text to be placed on
each input line as comments. Lines that begin with a comment delimiter char
acter are treated as blank lines by the parser-they are silently skipped, and the
iterator command is not executed. Common choices for an end-of-line character
are EOL= ; or EOL=#. Only a single character is allowed for the end-of-line
character.
The SKIP option skips the specified number of input lines before parsing begins.
This is a convenient way to skip past header information in text files, or head
ers generated as part of command output. If multiple text files are specified by
source, the SKIP option is applied to each file in turn.
The DELIMS option specifies an alternate token delimiter set. The default delim
iters are space and tab. Use the DELIMS option to specify an alternate delimiter
set. For example, DELIMS= , ; uses the semi-colon and comma characters as valid
delimiters. In this case, a comma or semi-colon is used to separate tokens on a
line. A comma delimiter is often used when parsing comma-delimited files.
In Windows NT 4.0, the FOR command does not correctly process the tab
character as a default delimiter. Therefore, if the source input contains
tab separated tokens, a DELIMS= option is needed to explicitly specify a tab
character as a separator. Follow the = sign with a single tab character.
The TOKENS option specifies which tokens are to be assigned to iterator vari
ables. By default, only the first token on each line is assigned to the iterator
variable specified in the FOR command ( var ) . Use the TOKENS option to explicitly
assign specific tokens. Specify a list of tokens to assign, separated by commas.
Chapter 4: Control Flow, Procedures, and Script Nesting 137
The EOL option eliminates the comments in the file, including the first line,
which only contains a comment and is therefore skipped. The DELIMS option
specifies a comma separator, and the TOKENS option assigns tokens 1 and 3 only.
Token 1 is assigned to the % I variable, and token 3 to the automatically created
%J variable. The ECHO command executes three times with the parsed informa
tion, resulting in the output shown.
The TOKENS=* option assigns the specified iterator variable all text on the input
line, excluding any text after the EOL character (if this option is also speci
fied). This effectively passes all processed text lines to the specified command,
138 Part I: The Script Language
with the exclusion of blank lines and lines excluded with the SKI P and EOL
options. For example:
1. C: \ >f o r / f " tokens=* " %1 in ( ' dir * . bat ' ) do @echo %1
2. Volume .in d rive c is BIGNTFS
3. Volume Serial Number is C095 - DBBC
4. Directory of C : \
5. 1 1 / 07 / 97 1 2 : 1 0p 384 MASTER . BAT
6. 1 1 / 07 / 97 1 2 : 08p 1 28 SLAVE . BAT
7. 1 1 / 05 / 97 1 0 : 46a 1 28 TEST . BAT
8. 3 File ( s ) 640 byt es
9. 571 , 9 1 4 , 240 bytes f ree
The output of the DIR command is essentially unaltered except that blank lines
are eliminated and leading spaces and tabs on lines are eliminated.
This FOR command extracts the file name from the specified argument and
stores it in the variable FILENAME. This type of parsing operation lets scripts
analyze arguments and extract information using a variety of argument
formats.
The output of commands can also be parsed. To parse command output, speci
fy the command to execute as the FOR command source. Place the command in
single quotes. The FOR command executes the specified command and captures
its command output, which is not displayed. This output is then used as the
source for the parsing operation in much the same way that a text file is
parsed. For example:
C: \>for / f " delims== token s=2 " %1 in ( ' set PROCESSOR_ARCHITECTURE ' ) do @echo %1
x86
This use of the FOR command was introduced in Chapter 3 when variable
arrays were described. The SET command in single quotes executes, and results
in the following command output (which is not actually displayed} :
PROCESSOR_ARCH ITECTURE=x86
This single line is then parsed. The DELIMS option breaks the line into two
tokens using the = sign as the delimiter. The TOKENS option then assigns the sec
ond token (the variable value) to the %1 iterator variable.
Chapter 4: Control Flow, Procedures, and Script Nesting 139
Any valid shell command can be used as a source, even another script.
Compound commands are also valid, but the command separators (such as &)
must be escaped.
The ability to capture and parse the output of commands is very powerful. Any
item of information that can be displayed by a command can also be captured
and processed by a script file. For example, the I PCONFIG command displays
information about TCP/IP configuration, including the IP address assigned to
the NIC. This can be captured and processed using the following command:
1 . C : \ >f o r / f " d elims= : tokens=2 " %! in ( ' ipconfig ' : find " I P Add ress '" ) do
@echo %!
2. 207 . 1 42 . 9 . 99
3. 0.0.0.0
The I PCONFIG command executes, and its output is piped to the F I ND filter. (The
pipe command character is escaped so that it is included in the command to
execute. ) The F I ND command filters lines containing the IP address text. These
lines are then parsed by the FOR command, which extracts the IP address from
each line and passes it to the ECHO command.
The first SET command deletes variable x. The second command sets variable xx
to the value %X%. Since variable x is not defined, the variable xx receives the lit
eral text %X%. The third SET command sets the value of x. The ECHO command
shows the lack of recursion; the shell substitutes for the variable %XX% as
expected, but the shell does not perform additional substitution. Therefore the
ECHO command does not display the contents of variable x, only the text %X%.
The initial value of the RET variable contains three indirect references to vari
ables that are not recursively substituted by the first ECHO command. In addi
tion, each of these variables itself contains further indirect variable references.
The variable %ZZZ% contains a reference to %ZZ% that in turn references %Z%. The
RESOLVE procedure resolves all these references, resulting in the fully substituted
output shown.
The RESOLVE procedure operates by repeatedly substituting environment vari
ables via an ECHO command, and then capturing the ECHO command output for
additional substitution, if required. The FOR command captures the output of
the command ECHO %RET%. This executes the ECHO command, and echoes the cur
rent contents of the RET variable. This output is captured by the FOR command,
and then the entire output line is parsed into the iterator variable %1. The SET
command then assigns this output back into the original RET variable.
The result of the FOR command is thus to provide one level of variable substitu
tion within the RET variable. The FOR command executes in a loop until the
value of the RET variable before and after the FOR command execution is identi
cal. This indicates that all variable substitutions are complete.
In the example script, the RET variable starts with:
%XX% and %VY% and %ZZZ%
After one execution of the FOR command, the new value of the variable is:
%X% and %Y% and %ZZ%
Chapter 4: Control Flow, Procedures, and Script Nesting 141
After the second execution of the F O R command, the new value of the variable is:
var X and var Y and %Z%
After the third execution of the FOR command, the new value of the variable is:
var X and var Y and var Z
The FOR command executes once more, and the I F command now detects that
there were no more changes to the RET variable, and the procedure exits.
The only restriction on the R ESOLVE procedure is that it does not handle recur
sion loops. If a variable expands to a reference to itself (directly or indirectly),
the R ESOLVE procedure never exits. This usually indicates a bug in the script,
and one solution is to count the number of passes around the RESOLVE loop. If
the number of passes reaches a high number (say, 1 00), then RESOLVE should
probably abort and display an error message.
Recursive variable substitution enables scripts to use variable indirection. That
is, a variable contains, instead of a value, the name of another variable that
contains a value. Examples of variable indirection include arrays and pointers,
both of which are the foundations of nearly all advanced programming tech
niques. Many of the example scripts in Part III of this book make use of the
R ESOLVE procedure.
s A . Ssri.pting T99lkit
�s.��·�fapa$J�e�,t Scripts
.
6 .
·
7 Miscellaneous Scripts
Chapter 5
A Scripting Toolkit
• Building scripts
Learn the tools and techniques needed to construct robust scripts.
• Standard script skeleton
This section provides a complete script skeleton that can be used as the
starting point for any new script project.
• Standard library skeleton
Complete libraries of script procedures can be constructed using the
library skeleton described in this section.
• An example library
This sample library provides many useful procedures that are used by the
other sample scripts in this book.
Building Scripts
This chapter provides guidelines for using tools to build scripts, and also pro
vides two complete script skeletons: templates that can be used as starting
points for customized scripts. In addition, the _MTPLIB.BAT script library
source code is presented and described in detail. This library contains many
useful procedures that can be accessed directly from custom scripts. The sam
ple scripts of Chapter 6 and 7 also make extensive use of the _MTPLIB.BAT
script library.
The sample scripts in this chapter are available for downloading from the
MTP web site at http://www.macmillantech.com.
146 Part II: Real-World Scripting
Because scripts are text files, the only real tool needed when developing a script
is a good text file editor. However, certain special script requirements place
two specific constraints on this editor:
• First, some scripts require trailing spaces at the end of a line (for exam
ple, the PJCOUNT.BAT script of Chapter 6). Therefore, check that the
editor does not automatically strip trailing white space from lines.
• Second, a FOR command bug sometimes requires literal tab characters in
the script (for example, the _MTPLIB.BAT script of this chapter) . .
Therefore, make sure that any editor you use does not convert tab char
acters into spaces (or vice versa).
The Windows Notepad editor correctly handles both trailing spaces and literal
tab characters.
The only other (and most important) tool needed to develop a script is good
programming discipline. Scripts are often seen as " quick and dirty" solutions
to one-off problems. Typically, however, the quick and dirty script takes on a
life of its own and is modified and enhanced until it has far outgrown its hum
ble origins. More robust and manageable scripts result when each script, how
ever small, is treated as a simple programming project. The skeleton scripts in
this chapter are good starting points for any script and encourage a structured
approach to script creation.
The command shell does not offer any built-in script debug facilities, other
than the capability to enable and disable script command echo (using the ECHO
command) . The following techniques may prove helpful when debugging
scripts:
• Use the standard preamble shown in the skeleton scripts in this chapter,
and disable/enable script tracing using the ECHO variable.
• Use the TRACE variable shown in the skeleton scripts in this chapter.
• Add ECHO commands when developing a script to show intermediate vari
able values, control flow, and exit codes (via %ERRORLEVEL% ) . These can be
removed when development is complete.
• Add PAUSE commands before a critical part of a script, so that the script
can be stopped if something appears to be wrong. These can be removed
when development is complete.
• Add ECHO commands to preview complex or "dangerous " commands
{such as a command which deletes lots of files) before they are executed.
Add a PAUSE command after the ECHO command but before the actual
execution of the command.
Chapter 5: A Scripting Toolkit 147
Most of these techniques are highlighted in the sample script presented in this
chapter.
2. Add ECHO commands to the HELP procedure to display brief on-line help
information.
5. Create additional procedures used by MAI N following the end of the MAI N
procedure and before the DOSEXIT label.
Although SKELETON. BAT does not do anything, it does bring together many
of the structural suggestions mentioned in Part I of this book into a complete,
ready-to-use script. After some initial setup, the script calls a procedure named
MAI N at line 1 5, and passes to this procedure all of the command line argu
ments. The MAI N procedure should contain the program logic of the script.
When the MAI N procedure exits, the entire script exits. Template code surround
ing the MAI N procedure handles all of the logic needed to make the script a
"good citizen"-a local scope for variables is created, and the current state is
saved.
Before the MAI N procedure is called, the template logic checks to see if the first
argument is either / ? or / HELP (lines 1 3 and 1 4 ) . In this case, the HELP procedure
is called instead of MAI N . Typically, this procedure displays a short help message
describing the use of the script.
The first two lines of SKELETON.BAT ( shown in Figure 5.1) provide the com
mand echo management discussed in Part I. When the script is executed, if the
variable ECHO has the value ON, then script command echo is enabled. If the vari
able ECHO has the value OFF or is not defined, then script command echo is dis
abled.
The third line checks the operating system type. If the script is run on an OS
other than Windows NT, the script j umps immediately to the DOSEX IT label.
148 Part II: Real-World Scripting
This label, located at the very end of the script, simply displays a warning mes
sage and then ends script execution by " falling off" the end of the file. Thus, if
a script based on this skeleton is run on an OS other than Windows NT, it
simply displays:
This sc ript requires Windows NT
One implication of this code is that the first three lines of the script and all the
lines following the DOSEXI T label must be syntax-compatible with MS-DOS,
Windows 3 . 1 , Windows 95, and OS/2. This is why, for example, there is no
colon character preceding the DOSEXI T label on line 3. Once past that line, how
ever, all of the syntax enhancements provided by Windows NT can be safely
used.
01 . @echo OFF
02 . @if not " %ECHO% " == " " echo %ECHO%
03 . @if not " %0S% " == "Windows_NT " goto DOSEXIT
04 . rem $Workf ile : skeleton . bat $ $Revision : 2 $ $Dat e : 1 2 / 04 / 97 9 : 5 1 a $
05 . rem $Archive : / TimH / Pubs / Books / Macmillan /Windows NT
Scripting / Scripts / skeleton . bat $
06 .
07 . rem Set local scope and call MAIN procedure
08 . setlocal & pushd & set RET=
09 . set SCRI PTNAME=%-n0
10. set SCRI PTPATH=%-f0
11 . if " %DEBUG% " == " 1 " ( set TRACE=ech o ) else ( set TRACE=rem)
12. call _mt plib : !NIT %SCRIPTPATH%
13. if / i {%1 }=={ / help} ( call : HELP %2 ) & ( goto : HELPEXIT)
14. if / i {%1 }=={ / ? } ( call : HELP %2 ) & ( goto : HELPEXIT)
15. call : MAIN %*
16. : HELPEXIT
17. popd & endlocal & set RET=%RET%
18. goto : EOF
19.
20 . rem / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
21 . rem HELP procedure
22 . rem Display brief on - line help message
23 . rem
24 . : HELP
25 . if defined TRACE %TRACE% [ proc %0 %* ]
26 . rem Put help message here . . .
27 .
28 . goto : EOF
29 .
30 . rem / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
31 . rem MAIN proced u re
32 . rem
Chapter 5: A Scripting Toolkit 149
33 . : MAIN
34 . if defined TRACE %TRACE% [ proc %0 %* )
35 . rem Put main script code here . . .
36 .
37 . goto : EOF
38 .
39 . rem / l l / l l l l l l l l / l l l l l l l l l / l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l
40 . rem Additional procedures g o here . . .
41 .
42 . rem These must be the FINAL LINES in the script . . .
43 . : DOSEXIT
44 . echo This script requires Windows NT
45 .
46 . rem l l l / l l l l l / l l l l l l l / l l l l l l l l l l l / l l l l l l l l l l l l l l l l l l l l l l / l l l l l l l l l l l l l l l l l l
Following the initial setup lines is the main script body. In outline, this is con
structed as follows:
1 . setlocal & pushd & set RET=
2.
3.
4 . popd & endlocal & set RET=%RET%
5 . goto : EOF
The first line creates a local scope for variables as well as the current drive and
directory (via the SETLOCAL and PUSHD commands) . After the script body, a cor
responding set of commands, E NDLOCAL and POPD, close the local scope. This
makes the script "well behaved" and preserves the current drive and directory,
as well as all environment variables. It also means that code within the script is
free to alter any variable, as any changes made are automatically restored
when the script completes.
The RET variable is also initialized by the script body code, and the variable tun
neling technique described in Chapter 3 is used to pass the RET value back from
the script ( SET RET=%RET% on the same line as ENDLOCAL ) . Thus, after the script exe
cutes, the only change in the environment will be the RET value. This means that
the SKELETON.BAT script can be used to develop complete script procedures
that can be called from other scripts and return results via the RET variable.
The main script body between the local scope " brackets" described previously
is as follows:
1 . set SCR I PTNAME=%-n0
2 . set SCR I PTPATH=%-f0
3 . if "%DEBUG% " == " 1 " ( set TRACE=echo ) else ( set TRACE=rem )
150 Part II: Real-World Scripting
The first two lines set two standard variables: SCRI PTNAME and SCRI PTPATH. The
SCR I PTNAME variable contains the name of the script (SKELETON, in this case).
Uses for the script name include constructing data file names (see the ANI
MAL.BAT script of Chapter 7), and choosing a Registry key name (see the
REPL.BAT script of Chapter 7). The second variable, SCR I PTPATH, contains the
full path to the script (even if the full path was not entered on the command
line). These two variables are set because the program logic in the MAI N proce
dure does not have direct access to the script name. (The %0 parameter within
the MAI N procedure has the value : MAIN, regardless of the script name.)
The third line in the main script body provides trace facilities. The variable
TRACE is either set to echo or r e m depending upon the value of the DEBUG variable.
If the DEBUG variable has the value 1 before the script is executed, then TRACE is
defined as echo. If the DEBUG variables has another value or is not defined, then
TRACE is defined as rem.
If the DEBUG variable is not 1, the TRACE variable is rem, and the statement
expands to:
rem Computing total size . . .
Obviously, the REM command does nothing. If, however, the DEBUG variable is 1,
the TRACE variable is echo, and the statement expands to:
echo Computing total size . . .
This displays the text in the console window. Thus, if DEBUG is 1 , all %TRACE%
prefixed commands display trace information. If DEBUG is not 1 , no output is
displayed. This allows script trace commands to be embedded throughout a
script and enabled or disabled just by changing the DEBUG variable before run
ning the script. All the sample scripts use this technique to display the names of
called procedures. Each procedure starts with this line:
if defined TRACE %TRACE% [ proc %0 %* ]
This displays the name of the procedure ( %0 ) and all the procedure arguments.
To ensure robustness, the line first checks that the variable TRACE is defined
(using the IF DEFINED command) before executing the trace statement.
Chapter 5 : A Scripting Toolkit 151
Following the TRACE setup command are one o r more library initialization pro
cedure calls. Only one script library, _MTPLIB.BAT, is initialized by the sample
skeleton script. If the script uses other libraries, the I N I T procedure for each
library should be called here. The use of script libraries and the I N I T procedure
are discussed in Chapter 4.
Finally, when all libraries have been initialized, the main script logic is invoked.
Depending upon the first argument, either the HELP or the MAI N procedure is
called. The MAI N procedure is passed all script arguments. The HELP procedure is
passed only the second argument, allowing a help context to be requested by
passing an additional argument following the / ? or / HELP switch.
library, some care must be taken to ensure that library procedures are well
behaved. Some things to watch out for include:
• Avoid changing state information, such as the current drive or directory
(unless that is a desired function of the library procedure). If it is neces
sary to alter these, use PUSHD and POPD to preserve the caller state.
• Avoid changing global variables. Create a local scope using SETLOCAL and
ENDLOCAL if extensive use is made of variables. If only one or two variables
are needed, use names prefixed by the name of the library (such as
_MYLIB_T1 ) , so that the names do not collide with those used in the caller
script.
• Pass return results back to the calling procedure in the RET variable. Pass
additional results in additional RET variables (such as RETX, RETV ) .
Document the return results carefully. It is good practice to initialize the
RET variable(s) to a default return value immediately upon entry to a pro
cedure.
• Pass arguments to the procedures as parameters. Avoid passing arguments
in variables unless there is a special need (for example, if the argument
contains a large amount of text). If arguments are passed in variables,
document this carefully. Also document any standard variables used by
the procedure (such as TEMP or PATH ) .
• Define label names carefully. Labels are global within a script file, so
using a label such as : LOOP isn't particularly friendly, as it will quite likely
collide with another label of the same name elsewhere in the library.
Within a procedure, prefix all label names with the procedure name.
(This advice applies equally to procedures in a regular script.)
The _LIBSKEL.BAT script begins with the same preamble lines as the SKELE
TON.BAT script, and ends with the same DOSEX I T label and code. The first line
following the preamble checks to see if any arguments are present. If not, the
script displays the library name and version information and then exits. If one
or more arguments are present, the script falls through into the dispatch code.
As explained in Chapter 4, a library procedure is called using an indirect CALL
command, which follows the CAL L command with the library name, procedure
name, and then procedure arguments. For example:
call _libskel : MYPROC arg 1 arg2
Here, the procedure MYPROC in the _LIBSKEL.BAT library is called with argu
ments a r g 1 and a rg2. The CALL command calls the _LIBSKEL.BAT library, pass
ing : MYPROC, a r g 1 and a rg 2 as three arguments. Eventually, the dispatch code in
_LIBSKEL.BAT is reached. This code is:
Chapter 5 : A Scripting Toolkit 153
1 . set _PROC=%1
2 . s hift / 1
3 . goto %_PROC%
The first line of the dispatch code saves the first argument (the procedure
name, in this case : MYPROC ) in the _PROC variable. The second line then shifts the
arguments, discarding the procedure name and moving all other arguments
down one place in the argument list. In the example above, this moves arg1 to
%1 and arg2 to %2. This is where these arguments are expected by the proce
dure. Finally, the third line jumps to the label specified by the _PROC variable
(that is, the procedure name specified in the original CALL command) . The
result of this processing is that the procedure specified in the original CALL com
mand is called and passed the arguments specified.
The _LIBSKEL.BAT script provides one sample procedure, : CHECKXB6, which
sets the RET variable to 0 or 1 depending upon whether the script is run on an
Intel x86 platform or not. This sample procedure also shows the use of the
TRACE variable described previously.
01 . @echo OFF
02 . @if not " %ECHO% " == " " echo %ECHO%
03 . @if not " %0S% " == "Windows_NT " goto DOSEXIT
04 . rem $Workfile : _libskel . bat $ $Revision : 2 $ $Date : 1 2 / 04 / 97 9 : 5 1 a $
05 . rem $Archive : / TimH / Pubs / Books / Macmillan /Windows NT
Scripting / Scripts /_libskel . bat $
06 .
07 . rem If no argument s , show version information and exit
08 . if "%1 " == " " (
09 . ( echo Script Library Skeleton ( %0 ) $Revision : 2 $ )
10. ( goto : EOF)
11 .
12.
1 3 . rem At least one argument , s o dispatch t o procedure
1 4 . set _PROC=%1
1 5 . s h ift / 1
1 6 . goto %_PROC%
17.
1 8 . rem / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
1 9 . rem !NIT procedure
20 . rem Must be called in local state before other procs are used
2 1 . rem
22 . : ! N IT
23 . if defined TRACE %TRACE% [ p roc %0 %* )
24 .
25 . goto : EOF
26 .
27 . rem / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
154 Part II: Real-World Scripting
An Example Library
The _MTPLIB.BAT script library shown in Figure 5.3 is a complete sample
library based upon the _LIBSKEL.BAT script library described in the previous
section. _MTPLIB.BAT contains a number of useful procedures that are used
by many of the sample scripts in Chapters 6 and 7, and can also be used by
other scripts as desired. To use this library, place it in a directory that is on the
system PATH. The SKELETON.BAT script already contains code to call the ! N I T
procedure o f this library.
The _MTPLIB.BAT library contains procedures to assist in the following tasks:
• Deleting multiple variables (by variable prefix).
• Parsing a command line for switches and positional arguments.
• Saving and restoring variables to/from the Registry.
• Generating pseudo-random numbers.
• Resolving recursive (nested and indirect) variable references.
• Reading a line of user input to a variable.
Chapter 5 : A Scripting Toolkit 155
077 .
078 . rem / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
079 . rem GETARG procedure
080 . rem Get a parsed argument by index
081 . rem
082 . rem Arguments : %1 =argument index ( 1 st arg has index 1 )
083 . rem
084 . rem Return s : RET=argument text or empty if no argument
085 . rem
086 . : GETARG
087 . if defined TRACE %TRACE% [ proc %0 %* )
088 . set RET=
089 . if %1 GTR %CMDARGCOUNT% goto : EOF
090 . if %1 EQU 0 goto : EOF
091 . if not defined CMDARG_%1 goto : EOF
092 . set RET=%%CMDARG_% 1 %%
093 . call : RESOLVE
094 . goto : EOF
095 .
096 . rem / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
097 . rem GETSWITCH procedure
098 . rem Get a switch argument by index
099 . rem
1 00 . rem Argument s : %1 =switch index ( 1 st switch has index 1 )
1 01 . rem
1 02 . rem Returns : RET=switch text o r empty if none
1 03 . rem RETV=swit ch value ( after colon char) or empty
1 04 . rem
1 05 . : GETSWITCH
1 06 . if defined TRACE %TRACE% [ p roc %0 %* )
1 07 . ( set RET= ) & ( set RETV= )
1 08 . if % 1 GTR %CMDSWCOUNT% goto : EOF
1 09 . if % 1 EQU 0 goto : EOF
1 10. if not defined CMDSW_%1 goto : EOF
111. set RET=%%CMDSW_%1 %%
1 12. call : RESOLVE
1 13. for / f " tokens= 1 * delims= : " %%I i n ( " %RET% " ) d o ( set RET=%%I ) & ( set
RETV=%%J )
1 1 4 . goto : EOF
1 15.
1 1 6 . rem / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
1 1 7 . rem FINDSWITCH procedure
1 1 8 . rem Finds the index of the named swit ch
1 1 9 . rem
1 20 . rem Arguments : %1 =switch name
1 21 . rem %2=search start index ( def : 1 )
1 22 . rem
1 23 . rem Retu rn s : RET=index (0 if not fou n d )
1 24 . r e m RETV=switch value ( text after colon )
158 Part II: Real-World Scripting
1 25 . rem
1 26 . : FI NDSWITCH
1 27 . if defined TRACE %TRACE% [ proc %0 %* ]
1 28 . if {%2}== { } ( set / a _MTPLI B_T4=1 ) else ( set / a _MTPLI B_T4=%2 )
1 29 . : FINDSWITCHLOOP
1 30 . call : GETSWITCH %_MTPLIB_T4%
1 31 . if "%RET% " == " " ( set RET=0 ) & ( goto : FI NDSWITCHEND )
1 32 . if / i " %RET% " == " %1 ' ( set RET=%_MTPL I B_T4%) & ( goto : FINDSWITCHEND )
1 33 . set / a _MTPLIB_T4+=1
1 34 . goto : FI NDSWITCHLOOP
1 35 . : FI NDSWITCHEND
1 36 . set _MTPLI B_T4=
1 37 . goto : EOF
1 38 .
1 39 . rem l l l l l l l l l l l l l / l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l
1 40 . rem REGSETM and REGSETU procedures
141 . rem Set regist ry values f rom variables
1 42 . rem
1 43 . rem Argument s : %1 =reg context ( usually script name )
1 44 . rem %2=variable to save ( o r pref ix to save set of vars )
1 45 . rem
1 46 . : REGSETM
1 47 . if defined TRACE %TRACE% [ proc %0 %* ]
1 48 . for / f " tokens=1 * delims== " %%I i n ( ' set %2 2A>nul ' ) d o call : REGSET1
HKLM %1 %%I " %%J "
1 49 . goto : EOF
1 50 . : REGSETU
151 . if defined TRACE %TRACE% [ p roc %0 %* ]
1 52 . for / f " tokens=1 * delims== " %%I i n ( ' set %2 2 · >nul ' ) d o call : REGSET1
HKCU %1 %%I " %%J "
1 53 . goto : EOF
1 54 . : REGSET1
1 55 . set _MTPLIB_T1 0=%4
1 56 . set _MTPLIB_T1 0=%_MTPLIB_T1 0 : \ = \ \%
1 57 . reg add %1 \ Software \ MTPSc riptContexts\%2\%3=%_MTPLIB_T1 0% >nul
1 58 . reg update %1 \ Software\MTPSc riptContexts \%2 \ %3=%_MTPLIB_T1 0% >nul
1 59 . goto : EOF
1 60 .
1 61 . rem /lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
1 62 . rem REGGETM and REGGETU procedures
1 63 . rem Get regist ry value o r values to variables
1 64 . rem
1 65 . rem Argument s : %1 =reg context ( us ually sc ript name )
1 66 . rem %2=variable to restore ( def : restore entire context )
1 67 . rem
1 68 . rem Retu rns : RET=value of last variable loaded
1 69 . rem
1 70 . rem WARNING : The " delims " value in the FOR commands below is a TAB
Chapter 5 : A Scripting Toolkit 159
VARDE L
Deletes a set of variables by prefix.
Syntax
CALL _MTPLIB : VARDEL prefix
Arguments
prefix Prefix of variables to be deleted.
Description
The VARDEL procedure deletes one or more environment variables sharing a
common prefix. For example, specifying a prefix of JOB_ deletes all variables
that begin with JOB_. One common use of VARDEL is deleting all members of an
array by specifying the array name as the prefix.
Implementation
VARDEL executes a SET command (line 35) with the specified prefix without
an equal sign following it. This command displays all variables that match this
prefix (in the form name=value ) . The output of this SET command is captured by
a FOR command and parsed. Each line is parsed for the first token, using = as
the delimiter, which yields the variable name. The FOR command then executes
the command SET name= for each parsed name, thus deleting each variable
which matches the prefix.
The command error output of the first SET command is redirected to the NUL
device (in other words, discarded). This takes care of the situation in which no
variables match the specified prefix (in this case, the SET command displays an
error message, which is captured and discarded by this redirection). Notice the
use of the escape character ( ) before the redirection symbol in the SET com
A
mand. This ensures that the redirection is processed when the SET command is
executed, not when the FOR command is executed.
PARSECMD L I N E
Parses a command line(s).
Syntax
CALL _MTPLIB : PARSECMDLINE [ append]
Arguments
CMDLINE Contains the text of the command line to parse.
append 0 (the default) to perform a new parse, 1 to append to existing parse.
164 Part II: Real-World Scripting
Returns
RET Total number of arguments parsed.
CMDARGCOUNT Count of arguments in CMDARG_n array.
CMDARG_n Command arguments ( CMDARG_1 contains first argument) .
CMDSWCOUNT Count o f switches i n CMDSW_n array.
CMDSW_n Command switches ( CMDSW_1 contains the first switch) .
Description
The PARSECMDL I N E procedure parses a command line, separating the arguments
into switches and positional arguments. In most Windows NT commands, a
switch is a command argument preceded by a I or - character. Switches can
generally appear anywhere on a command line, intermixed with regular (posi
tional) arguments. Switches can also contain optional values, which follow the
switch and are separated by a colon. For example,
/ SRC : \ \ t ransit \files
The command line to parse is passed in the CMDL I N E variable, not as an argu
ment. Typically, this variable is initialized with the %* parameter (which con
tains the entire command line). However, it can also be initialized from other
variables or from the contents of a data file. This allows PARSECMDLINE to parse
command text from many different sources.
PARSECMDL INE takes one optional argument. If this argument is 0 (the default), a
new parse operation is performed, and any previous parse results are discard
ed. If this argument is 1 , the new command line information is appended to
any existing parse results. This allows multiple command lines to be merged
together and processed as a single line.
Positional (that is, non-switch) arguments parsed by PARSECMDL I N E are placed in
the CMDARG_n array. The first argument is placed in CMDARG_1 . A count of all posi
tional arguments is stored in CMDARGCOUNT. Double quotes are stripped from
arguments before they are stored in the array. (See Chapter 3 for a discussion
of double quotes.) The arguments are stored in the array in the same order as
they occurred in the command line.
Chapter 5 : A Scripting Toolkit 165
Switch arguments parsed by PARSECMDL I N E are placed in the CMDSW_n array. The
first switch is placed in CMDSW_1 . A count of all switches is stored in CMDSWCOUNT.
Double quotes are stripped from switches before they are stored in the array.
The switches are stored in the array in the same order as they occurred in the
command line.
Implementation
After performing some variable initialization, PARSECMDL I N E calls PARSECMD L I NE 1 ,
passing it the contents o f the CMD L I N E variable as an argument. The normal
command shell parsing mechanism thus performs most of the work of splitting
the contents of the CMDL INE variable into individual arguments.
PARSECMDL I N E 1 then runs a loop to process each parameter (lines 61 to 75 ).
After parameter %1 is processed, the S H I FT command (line 66) shifts the para
meters down, and the loop repeats until parameter %1 is empty (line 62), and
hence, all parameters have been processed.
Parameter processing begins by removing double quotes via string substitution
(lines 63 and 64). The first character of the parameter is then compared to the
switch characters I and - (lines 67 and 6 8 ) . If a match occurs, the parameter is
added to the switch array (lines 72 to 75 ). Otherwise, the parameter is added
to the positional argument array (lines 69 to 71 ).
GETARG
Obtains a positional argument from a parsed command line, by index.
Syntax
CALL _MTPLIB : GETARG index
Arguments
index Index of argument to fetch. The first argument is numbered 1.
Returns
RET Argument text, or empty if index is greater than CMDARGCOUNT.
Description
The GETARG procedure recovers a single positional argument from a command
line that has been parsed by the PARSECMDL I N E procedure. The single argument
specifies the index of the argument to return, which must be between 1 and
GETARGCOUNT. The argument is returned in the RET variable. The returned argu
ment will not contain double quotes.
166 Part II: Real-World Scripting
Implementation
After performing some basic error checking, the core of the GETARG procedure is
a SET command (line 92):
set RET=%%CMDARG_%1 %%
If the index specified is 3, for example, the RET variable contains %CMDARG_3%.
This is the name of the variable containing the desired value. GETARG then calls
the RESOLVE procedure (described later in this chapter) to convert the name of
the variable into its value, which is the desired argument.
GETSWI TCH
Obtains a switch argument from a parsed command line, by index.
Syntax
CALL _MTPL IB : GETSWITCH i ndex
Arguments
index Index of switch to fetch. The first switch is numbered 1.
Returns
RET Switch text (name), or empty if index is greater than CMDSWCOUNT.
RETV Switch value (text following colon) or empty if no value.
Description
The GETSWITCH procedure recovers a single switch and its value (if any) from a
command line that has been parsed by the PARSECMDL INE procedure. The single
argument, which must be between 1 and GETSWCOUNT, specifies the index of the
switch to return.
The argument name is returned in the RET variable (including the I or - charac
ter) and the argument value (if any) in the RETV variable. The returned switch
and value will not contain double quotes.
Implementation
GETSWI TCH is similar in implementation to GETARG, except that it contains an
additional step after the switch text has been recovered into the RET variable.
This step uses a FOR command (line 1 1 3 ) to parse the text into the switch name
and value. The name includes all text up to the first colon; the value includes
all text after the first colon. Notice that the tokens value in the FOR command is
tokens=1 * and not tokens=1 2. This allows the switch value to contain any text,
,
F I NDSWI TCH
Finds a switch argument from a parsed command line by name.
Syntax
CALL _MTPLI B : FINDSWITCH name [ s tart -index ]
Arguments
name Name of switch to locate (with leading I or · character).
start - i ndex Starting index for search (the default is 1).
Returns
RET Index of switch, or 0 if not found.
R ETV Switch value (text following colon), or empty if no value or not
found.
Description
The F I NDSWITCH procedure searches for a switch value by name in a command
line that has been parsed by the PARSECMDLINE procedure. The first argument
specifies the name of the switch to find (including the leading I or - character).
The name is not case-sensitive. The search starts at the first switch unless
s tart - i ndex is present, in which case the search starts at the index specified
( s tart - index must be less than or equal to CMDSWCOUNT ) . Using s tart - index
allows multiple switches of the same name to be sequentially processed.
The switch index is returned in the RET variable. The value 0 is returned if the
switch cannot be located. The value of the switch (if any) is returned in the
RETV variable.
Implementation
F I NDSWI TCH is implemented as a simple loop (lines 129 to 1 34) that
calls
GETSWITCH for each index until a matching switch name is found or the end of
the switch array is reached. The I F command (line 1 32), which compares the
switch names, uses the I I switch to perform a case-insensitive comparison.
Syntax
1 . CALL _MTPLI B : REGSETM context prefix
2 . CALL _MTPL IB : REGSETU context prefix
Arguments
context Registry context (location) . Typically the script name.
prefi x Prefix of variables to be saved in Registry.
168 Part II: Real-World Scripting
Description
The REGSETM and REGSETU procedures save one or more variables in the Registry.
These procedures thus provide a way for a script to maintain persistent state
information, even across system restarts. The REGSETM procedure stores the vari
ables in the HKEY_LOCAL_MACHINE portion of the Registry, while the
REGSETU procedure stores the variables in the HKEY_CURRENT_USER portion
of the Registry.
In order to distinguish one script's state from another, each script must specify
a context for the variables. This same context is used when restoring the vari
ables via the REGETM and REGGETU procedures. Typically, the script uses the script
name as the context value. If the script is based on the SKELETON.BAT tem
plate, the script name is available in the SCR I PTNAME variable.
The variables to save are specified by the prefix argument. Like the VARDEL pro
cedure, the REGSETU/REGSETM procedures save all variables that have a prefix that
matches prefix.
Each variable is stored as a REG_SZ registry value. The values are placed in
the key HKEY_LOCAL_MACHINE\Software\MTPScriptContexts\context for
REGSETM and HKEY_CURRENT_USER\Software\MTPScriptContexts\context
for REGSETU.
Implementation
Both REGSETM and REGSETU are similar to the VARDEL procedure. They use a SET
command in a FOR command to extract a list of all variables which match the
specified prefix. The procedures then call the procedure REGSET1 for each
matching variable, passing it the root key name (HKLM or HKCU), the name
of the variable, and the variable value (in double quotes, as it can contain
spaces). REGSET1 then executes a REG command (lines 157 and 1 5 8 ) to store the
passed value into the appropriate registry key. Both a REG ADD and a REG UPDATE
command are executed, as the procedure has no way of knowing if the variable
already exists in the Registry.
The REG command has one undocumented peculiarity. In the value string
passed, the backslash character is treated as an escape character to allow spe
cial values to be passed. Therefore, before the variable values are stored in the
Registry, each backslash character is converted to a double backslash.
Syntax
1 . CALL _MTPLIB : REGGETM context [ variabl e ]
2 . CALL _MTPLIB : REGGETU context [ variabl e ]
Arguments
context Registry context (location) . Typically the script name.
variable Name of variable to restore (optional; default restores entire
context) .
Returns
RET Value o f last ( o r only) variable loaded.
Description
The REGGETMand R EGGETU procedures reverse the actions of the REGSETM and
R EGSETUprocedures, and restore one or more variables from the Registry. The
REGGETM procedure restores the variables from the HKEY_LOCAL_MACHINE
portion of the Registry, while the REGGETU procedure restores the variables from
the HKEY_CURRENT_USER portion of the Registry.
The context specifies the context from which to restore the variables. It should
be the same context name that was used to store the variables. Typically, the
script uses the script name as the context value. If the script is based on the
SKELETON.BAT template, the script name is available in the SCRI PTNAME
variable.
To restore an individual variable, specify it using the variable argument. To
restore all the variables from a context, omit the variable argument. When
restoring a complete context, only variables that are found in the Registry are
altered. Therefore, before calling REGGETM or REGGETU, preset all variables with
default values.
Implementation
These procedures use a REG QUERY command (lines 1 77 and 1 8 1 ) to recover the
contents of the variables. The output of this command is somewhat verbose,
but by filtering the output by a FIND command, only those lines that actually
define a variable are isolated. The entire REG/FIND command is captured by a
FOR command and parsed to extract the variable name and value, which is then
used in a SET command to restore the variable.
The procedures must also undo the doubled backslash processing performed by
the REGSETM and REGSETU procedures. Double quotes are also removed from the
variable values.
1 70 Part II: Real-World Scripting
Syntax
CALL _MTPL I B : REGDELM context [ variabl e ]
CALL _MTPLIB : REGDELU context [ variabl e ]
Arguments
context Registry context (location). Typically the script name.
variable Name of variable to delete ( optional; the default deletes the entire
context).
Description
The REGDELM and REGDELU procedures delete one or more variables from the
Registry. The REGDELM procedure deletes the variables from the
HKEY_LOCAL_MACHINE portion of the Registry, while the REGDELU proce
dure deletes the variables from the HKEY_CURRENT_USER portion of the
Registry.
The context specifies the context from which to delete the variables. It should
be the same context name that was used to store the variables. Typically, the
script uses the script name as the context value. If the script is based on the
SKELETON.BAT template, the script name is available in the SCRI PTNAME
variable.
To delete an individual variable, specify it using the variable argument. To
delete all the variables from a context, omit the variabl e argument.
Implementation
The core of these procedures is a REG DELETE command (lines 202 and 209).
Since this command prompts for confirmation before proceeding with the
delete operation, a temporary file is created containing the needed response,
and the console input of the REG command is redirected to this file. Early ver
sions of the REG command supported the / F switch to skip this confirmation,
but newer versions do not, so these procedures avoid the use of this switch.
SRAND
Seeds the random number generator.
Syntax
CALL _MTPLIB : SRAND value
Arguments
val ue New seed value.
Chapter 5 : A Scripting Toolkit 171
Description
The SRAND procedure can be used to re-seed the random number generator used
by the RAND procedure. This has the effect of changing the sequence of pseudo
random numbers generated by RAND.
Implementation
The RAND procedure keeps the current seed in the _MTPLI B_NEXTRAND variable.
Therefore, all this procedure does is assign a new value to this variable.
RAND
Generates a pseudo-random number.
Syntax
CALL _MTPLIB : RAND
Returns
RET Next pseudo-random number.
Description
The RAND procedure returns the next pseudo-random number in the pseudo
random sequence used by the generator. Each call to RAND returns a new value
in the R ET variable. These values are between 0 and 32767, inclusive.
Implementation
The algorithm used is based upon that recommended by ANSI for the standard
C language library. The algorithm is fast and simple, and generates numbers
with uniform distribution. It should not, however, be used for serious statistical
analysis.
The RAND procedure stores the current seed in the _MTPLI B_NEXTRAND variable,
which is updated each time RAND is called. If _MTPLI B_NEXTRAND is not defined,
the procedure defines it with an initial value of 1 { line 23 3 ) . This initialization
could be performed by the I N I T procedure of the _MTPLIB library, but placing
the initialization within the procedure improves the localization and makes the
procedure self-contained.
RESOLVE
Resolves recursive and nested variable substitution.
Syntax
CALL _MTPL IB : RESOLVE
Arguments
RET Text containing variables to be resolved.
1 72 Part II: Real-World Scripting
Returns
RET Text with all variable references resolved.
Description
The R ESOLVE procedure implements the technique described in Chapter 3 to
handle recursive and nested variable substitutions. The command shell scans all
script commands for variable references to expand. However, if the value of a
variable that is expanded contains additional variables to expand, these are not
expanded. The RESOLVE procedure overcomes this limitation by providing a
fully recursive variable expansion facility.
Before calling RESOLVE, the R ET variable should contain the text to be processed.
This text can contain any number of variable references (each surrounded by
percent signs, as usual). In addition, the value of any of these variables can also
contain variable references to resolve and so on to any nesting depth. After
R ESOLVE has been called, the RET variable contains the original text, with all
variable substitutions fully resolved.
RESOLVE is particularly useful when variable information must be accessed indi
rectly (for example, when arrays of data are accessed), or a variable name must
be composed from fragments and then resolved. It is used extensively in the
_MTPLIB library and throughout the sample scripts.
Implementation
The key to the R ESOLVE procedure is to execute the command ECHO %RET% and
capture the output of this command back into the RET variable (line 25 1 ) . In
the process of executing the ECHO command, any variable substitutions within
the text of the RET variable are resolved. The new text (with the variable substi
tutions made) is then stored back into the R ET variable, thus resolving one layer
of variable indirection.
The FOR command is used to capture the output of the ECHO command. No
actual parsing is done, as the entire contents of the ECHO command output are
assigned back to the R ET variable. To allow any depth of nested substitution to
occur, the FOR/ECHO commands are executed in a loop (lines 248 to 252 ) . The
loop terminates when the contents of the RET variable before and after the
FOR/ECHO commands are unchanged. This indicates that no more variable substi
tution is required.
GET I N PUTL I N E
Reads a line of input.
Syntax
CALL _MTPL IB : GETI NPUTL INE
Chapter 5 : A Scripting Toolkit 1 73
Returns
RET Line of text read (can be empty).
Description
The GETI NPUTLINE procedure reads a single line of text from the keyboard and
returns it in the RET variable. This allows a script to prompt for and receive
interactive input. To terminate the input line and continue script execution,
press Ctrl+Z followed by Enter (or the other way around) .
���&;�g:{[:fi@iJ��'{lfititiKr:lifiv.;,.·;';·.
There is a bug in the CHOICE command that ships with the resource kit.
After a CHOICE command executes, all subsequent COPY commands that
read from the console do not echo typed characters. This therefore dis
ables keyboard echo for the GETI NPUTLINE procedure. To avoid this prob
lem, execute the CHO I CE command in a sub-shell (using CMD / C) .
Implementation
GET I NPUTLINEuses the COPY command (line 265) to capture keyboard input. This
means that Ctrl+Z (in addition to Enter) must be typed to terminate the input
line. The line is copied to a temporary file, and this file is then parsed by the
FOR command to capture the file contents into the RET variable.
The FOR command (line 266) actually parses the results of a TYPE command,
rather than parsing the temporary file directly. This is because the FOR com
mand cannot correctly process a file name containing spaces (it mistakenly
assumes that the spaces separate multiple file names) . Instead, the TYPE com
mand (which can correctly handle file names with spaces) is used, and its
output is parsed.
G ETSYNCF I L E
Obtains the name of a synchronization file.
Syntax
CALL _MTPLIB : GETSYNCFI LE
Returns
RET Name of the file to use for synchronization.
Description
The GETSYNCFILE procedure returns the name of a file that can be used by the
SETSYNCFI LE, WAITSYNCFI LE, and DELSYN F I L E procedures for script synchronization
purposes. The file name is returned in the RET variable.
1 74 Part II: Real-World Scripting
Typically, GETSYNCF I L E is called by the "master" script, which then passes the
file name to the "slave" script either as a command line argument or in a
variable.
Using files for script synchronization is described in Chapter 4.
Implementation
GETSYNCFILE is simply a wrapper procedure for the GETTEMPNAME procedure.
SETSYNCF I L E
Sets a synchronization file.
Syntax
CALL _MTPL I B : SETSYNCFILE filename
Arguments
fil ename Name of the file to set. Typically obtained from GETSYNCFILE.
Description
The SETSYNCF I LE procedure "sets " the synchronization file. This causes any
scripts which are waiting for the file to be set (via the WAI TSYNCF I LE procedure)
to continue execution. A synchronization file is "set" by being created. A slave
script typically sets a synchronization file to indicate to a master script(s) that
it has completed processing.
The file to set is specified by fil e name , which is typically a name returned by
the GETSYNCF I LE procedure.
Using files for script synchronization is discussed in Chapter 4.
Implementation
A file is "set" by being created. Therefore, the procedure simply uses the ECHO
command (line 290) to output a single period character to the file.
DE LSYNC F I L E
Deletes a synchronization file.
Syntax
CALL _MTPLIB : DELSYNCFILE filename
Arguments
filename Name of the file to delete. Typically obtained from GETSYNCFILE.
Chapter 5 : A Scripting Toolkit 175
Description
The DELSYNC F I L E procedure deletes a synchronization file after it has been used.
The file to delete is specified by the fil ename argument. Typically, this file name
is obtained using the GETSYNCF I LE procedure.
DELSYNCFILE should be called to delete the synchronization file after it has been
used. Otherwise, the Windows temporary directory will gradually fill with old
synchronization files. After DELSYNC F I L E has been called, it is possible to use the
same file again for another synchronization event.
Using files for script synchronization is discussed in Chapter 4.
Implementation
DELSYNCF I L E is simply a wrapper for the DEL command.
WAI TSYNC F I LE
Waits for a synchronization file.
Syntax
CALL _MTPLIB :WAITSYNCFILE filename [ timeout]
Arguments
filename Name of the file to wait for. Typically obtained from GETSYNCFILE.
timeout Timeout period, in seconds (the default is 60) .
Returns
RET Timeout remaining, o r 0 i f a timeout occurred.
Description
The WAITSYNCF I L E procedure waits for a synchronization file to set. The file
upon which to wait is specified by the fil ename argument. The procedure waits
for up to timeout seconds (the default is 60 seconds) before failing with a time
out. Typically, a master script waits for a slave script to complete by using the
WAITSYNCF I L E procedure.
Implementation
WAITSYNCFILE contains a simple loop (lines 3 1 7 to 320) that checks for the exis
tence of the specified synchronization file. The loop (and procedure) exits as
soon as the file exists. While the file does not exist, the loop continues. Each
pass through the loop contains a SLEEP 1 command, which suspends execution
for 1 second. Thus, the file is polled every second until it exists. Forcing the
1 76 Part ll: Real-World Scripting
script to sleep for one second also yields the CPU while the script is waiting,
and the loop thus consumes almost no CPU time while waiting.
Since the loop executes once per second (approximately), the timeout code sim
ply counts down until the timeout reaches zero, at which time the loop executes
regardless of the state of the synchronization file. Notice the use of the double
IF command (line 320) to create an AND condition. This can be interpreted as
"if the timeout has not expired and the synchronization file does not exist,
continue looping. "
GETTEMPNAME
Creates a unique temporary file name.
Syntax
CALL _MTPLIB : GETTEMPNAME
Returns
R ET Temporary file name (can contain spaces) .
Description
The GETTEMPNAME procedure creates a temporary file name that can be used for
temporary storage of data. The file name is guaranteed not to exist and to be
in a location where unrestricted read/write access is permitted.
Implementation
The temporary file name is formed from the prefix -SH, a pseudo-random num
ber, and the suffix TMP. The pseudo-random number uses the same algorithm
.
as the RAND procedure, though it uses an independent seed value. If the TEMP
variable exists, it is used as the path name for the file. Otherwise, if the TMP
variable exists, it is used as the path name. Otherwise, the %SYSTEMROOT%
directory is used.
Chapter 6
User Management Scripts
• MAKEUSR script
This script automates the task of new user account creation.
• USRQUOTA script
Disk quota management can be automated using this sample script.
• PJCOUNT script
This sample script generates a report on print job activity, and can be
used as the basis of many other event log analyses scripts.
• MTPLOGON script
This sample logon script can be used as-is or customized for local site
requirements.
The sample scripts in this chapter are available for downloading from the
MTP Web site at http://www.macmillantech. com.
Syntax
MAKEUSR username [ password * I [ swi tches ]
Switches
/ DOMAIN Creates the account in the domain (the default is to
create the account on the local computer) .
/ LOCAL : group Adds the user account t o the specified local group.
More than one I LOCAL switch can be specified.
/GLOBAL : group Adds the user account to the specified global group.
More than one /GLOBAL switch can be specified.
/ FULLNAME : name Specifies the full user name. Use double quotes if the
name contains spaces.
/ PROF I LEPATH : path Specifies the location of the user profile for this
account.
/ SCRI PTPATH : pa th Specifies the name of the logon script for this account.
/ HOMEDIR : p a th Specifies the home directory path for this account.
/ HOMECOMPUTER : computer Specifies the home directory computer for this
account.
/ HOME PROTO : uncpath Specifies the UNC path to a prototype home directory.
/ COMMENT : text Specifies a comment for this user account.
Description
The MAKEUSR script creates a new user account. By default, the account is
created in the account database of the computer on which MAKEUSR is exe
cuted. Use the / DOMAI N switch to create the account in the domain instead.
Chapter 6: User Management Scripts 1 79
The account is given the name specified by username, and the password speci
fied by password. If an asterisk is used instead of pass word, then the script
prompts for the password (which does not echo when entered) .
The / FULLNAME switch specifies a full name for the user (enclosed in double
quotes if it contains spaces). The / PROF I LEPATH switch specifies the profile path
for the account, while the / SCRI PTPATH switch specifies a script name for the
account. The / COMMENT switch specifies an arbitrary comment for the account.
Each of these switches corresponds to a switch of the NET USER command.
Additional N ET USER switches can be specified using the MUNETUSER variable. This
allows switches and settings common to blocks of accounts to be specified
once in this variable.
(The / FULLNAME, / PROF I LEPATH, / SCR I PTPATH and / COMMENT. switches are normally
specified on the command line as these values are typically unique for each
user account. )
After the account is created, MAKEUSR automatically adds the account to the
local and global groups specified by the / LOCAL and /GLOBAL switches. Enclose
the names in double quotes if they contain spaces. Multiple / LOCAL and / GLOBAL
switches can be specified, allowing the account to join many groups. In addi
tion, the MULOCAL and MUGLOBAL environment variables can contain additional
group names (separated by spaces). Thus, if many similar accounts are being
created, set the MULOCAL and MUGLOBAL variables before executing a set of MAKEUSR
commands.
The switch specifies the home directory for the account. If the
/ HOMED I R
/ HOMECOMPUTER switch is not specified, this home directory path is assumed to be
on the local computer, and the path is assumed to be valid on this computer. If
the / HOMECOMPUTER switch is specified, the home directory is assumed to be rela
tive to the remote computer (for example, C:\ means the root of drive C: on
the remote computer) . In this case, MAKEUSR automatically creates a new
share on the specified home computer, called username$, and sets the home
directory to \ \ computer \ username$.
The / HOMEPROTO switch specifies the UNC name of a prototype home directory.
After the home directory is created, the content of the UNC name specified is
copied to the new home directory path. This allows a prototype directory and
files to be created for all users and then automatically copied into the (new)
home directory.
After the prototype directory (if any) is copied to the new home directory, the
permissions are set on this directory to grant full access to the new user
account. Additional permissions can be specified by adding XCACLS switches
to the MUXCACLS variable.
180 Part II: Real-World Scripting
Example
makeusr BobMacStart * / global : SalesAdm / global : Marketing
/ homedir : e : \ u s e rs \ BobMacSt art / homecomputer : CORP1 / domain
This example creates a new account called BobMacStart and joins the
SalesAdm and Marketing groups. The home directory is set to the
E:\USERS\BOBMACSTART on the server CORP l . The account is created in
the domain.
The MAKEUSR script can be used either stand-alone or embedded within a
batch processing script. For example:
1 . set MULOCAL=
2 . set MUGLOBAL=Software SrcSafe Pizza
3 . for / f " t okens=1 , 2 * " %%! in ( newaccts . txt ) do call : ADDUSER %%! %%J " %%K"
4. goto : EOF
5. : ADDUSER
6 . call makeus r %1 %2 / domain /f ullname : %3 / homedi r : d : \Users\%1
/ homecomputer : SYS · 1 1
7 . goto : EOF
This simple script reads an account file containing a list of new accounts to
create. Each line in the file must contain three fields, separated by spaces. The
first contains the user name, the second the password, and the third (the rest of
the line) the user's full name. For example:
BobDylan Secret 1 Bob Dylan
TonyBlair Secret2 Tony Blair
The script creates a new account for each name and adds each account to the
Software, SrcSafe, and Pizza global groups. Each account has a new (empty)
home directory created on the SYS-1 1 server, in the D:\USERS directory on
that computer.
The FOR command in line 3 above uses the " t o k e n s = 1 , 2 * " option to parse the
text file into arguments. Obviously, the first two tokens are the user name and
password. The third field, however, is captured using the * special token, rather
than token 3. This is done because the last field may contain spaces, and the *
token captures all remaining text on the line as the final (third) field.
Implementation
The MAKEUSR.BAT script is based on the SKELETON.BAT script described
in Chapter 5. The MAIN procedure first checks to see if any arguments are pre
sent (line 73 ). If not, then the help text is displayed and the script exits.
If arguments are present, the PARSECMDL I N E procedure in _MPTLIB.BAT is called
( line 77) to parse the command line, and the number of positional arguments is
then checked (it must be 2 or more). The command line is then processed.
Chapter 6: User Management Scripts 181
First, the USERNAME and PASSWORD variables are set from the first two positional
arguments (lines 79 to 82). Then all switch variables are preset to default val
ues (lines 85 to 8 8 ) .
Command line switches are processed i n the loop beginning at the
: GETSWITCHLOOP label {line 90). This loop {lines 90 to 104) repeatedly calls the
G ETSWI TCH procedure in _MTPLIB.BAT until all switches are processed. The I X
variable holds the switch index, which i s incremented each time the loop exe
cutes. Individual switches are then processed as follows:
• The / DOMAI N switch sets the DOMAI NSW variable to " / DOMA I N " {it is empty by
default).
• The / HOM ED I R, / HOMECOMPUTER, and / HOMEPROTO switches set corresponding
variables to the specified switch value.
• The / FULLNAME, / PROF I LEPATH, / SWI TCHPATH, and / COMMENT switches are added
to the M U N ETUSER variable {which can be preset before executing
MAKEUSR). These switches, and others supplied by the user, are all
passed unaltered to the N ET USER command.
• All / LOCAL switch values are appended to the M U LOCAL variable. Similarly,
all / GLOBAL switch values are appended to the end of the MUGLOBAL variable.
After switch processing is complete, the domain name is then stored in the
DOMAI N NAME variable by parsing the output of the WHOAM I [ RKJ command (lines
1 0 8 and 109). This is used by the XCACLS command later in the script.
After the setup is complete, the user account is created in a sequence of steps
(lines 1 12 to 1 1 6), each of which is handled by an individual procedure, as
follows:
• The procedure creates the new account home directory. The
MAKEHOME D I R
HOMEDI Rvariable is passed as an argument, as MAKEHOM ED I R uses the file
name qualifiers on this argument to parse various parts of the home
directory name (it cannot do this by operating directly on the HOM ED I R
variable).
• The CREATEUSER procedure actually creates the user account via a N ET USER
I ADD command.
• The SECUREHOM ED I R procedure secures the home directory by setting per
missions using the XCACLS command. SECUREHOM E D I R assumes that the home
directory is located on an NTFS volume.
• The ADDLOCALGROUPS and ADDGLOBALGROUPS procedures add the account to
the groups specified by the M ULOCAL and MUGLOBAL variables. These are
passed as an unquoted argument, which makes the command shell do the
work of parsing the variables into individual group names.
1 82 Part II: Real-World Scripting
• DOMAINSW
• HOMEDI RSW
The HOMEDI RSW is either empty (if no home directory is specified) or contains the
/ HOMEDIR switch and the home directory. Note that the home directory specified
to the NET USER command cannot be the same value supplied in the MAKEUSR
/ HOMEDIR switch. If a home computer is specified, the / HOMEDI R switch refers to
the share created by the MAKEHOMEDIR procedure.
The SECUREHOMEDIR procedure secures the new home directory by using an
XCACLS command (lines 1 74 and 1 77) to alter the permissions. The new user
account is given full control of the entire home directory tree. The MUXCACLS
variable can be used to pass additional switches to the XCACLS command. For
example, additional accounts can be given access to the home directory by
adding the appropriate XCACLS switches.
The ADDLOCALGROUPS and ADDGLOBALGROUPS procedures add the new user account
to one or more local or global groups. Each procedure receives a list of groups
as arguments. Both procedures run a loop that executes a NET LOCALGROUP /ADD
Chapter 6: User Management Scripts 183
or NET GROUP I ADD command to add the account to the specified groups. The
command arguments are shifted via the SH I FT command during each loop pass,
thus making the loop execute once for each passed argument.
1 79 . goto : EOF
1 80 .
1 81 . rem / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
1 82 . rem ADDLOCALGROUPS p rocedure
1 83 . rem Add user to each specified local group
1 84 . rem
1 85 . rem Argument s : \n=names of local g roups
1 86 . rem
1 87 . : ADDLOCALGROUPS
1 88 . if defined TRACE \TRACE\ ( proc %0 %* )
1 89 . if {%1 }== { } goto : EOF
1 90 . echo - - - net localg roup %1 \USERNAME\ / add \DOMAINSW\
1 91 . net localgroup %1 \USERNAME\ / add \DOMAINSW\
1 92 . shift / 1
1 93 . goto : ADDLOCALGROUPS
1 94 . goto : EOF
1 95 .
1 96 . rem / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
1 97 . rem ADDGLOBALGROUPS procedu re
1 98 . rem Add user to each specified g lobal g roup
1 99 . rem
200 . rem Arguments : \n=names of global g roups
201 . rem
202 . : ADDGLOBALGROUPS
203 . if defined TRACE \TRACE\ [ proc %0 %* )
204 . if {%1 }=={ } goto : EOF
205 . echo - - - net group %1 \USERNAME\ / add \DOMAINS\¥\;
206 . net group %1 \USERNAME\ / add \DOMAINSW\
207 . shift / 1
208 . goto : ADDGLOBALGROUPS
209 . goto : EOF
21 0 .
21 1 . rem / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
21 2 . rem Add itional procedures g o here . . .
21 3 .
21 4 . rem These must b e the FINAL L INES in the sc ript . . .
21 5 . : DOSEXIT
21 6 . echo This sc ript requires Windows NT
21 7 .
21 8 . rem / l l / l l l l l l / l l l l / l l l l l l l l l l l l l l l l l l l l l l l l l l l l / l l l l l l l l l l l l l l l l l l l / l l l l l
Multiple directories can be totaled and checked, and each user account can be
checked against a specified quota value. USRQUOTA can either generate a
report on all users, or only those who are over a preset quota amount. Quotas
for each account are stored in the user account database.
Syntax
USRQUOTA dir-list [ / QUOTA] [ / DOMAIN ] [ / OVER ]
Switches
/ QUOTA Restrict report to user accounts with assigned quotas.
/ DOMAIN Get assigned quota information from the domain (the default is to
get quotas from the local computer account database) .
/ OVER Restrict report t o user accounts that are over their quota limit.
Description
The USRQUOTA script provides a simple but effective quota checking facility
for disk space use. The dir-list argument specifies one or more directory
names (separated by spaces) . UNC names can be used, allowing any network
share to be included in the report. All directories in the dir - list must be on
NTFS volumes, as USRQUOTA relies upon the file ownership information
maintained by NTFS to compute per-user quotas.
Each directory specified by the dir - list argument is scanned, including all sub
directories, and the disk space used by each file found is accumulated on a per
user account basis. The owner of the file is used when decided which account
to charge for the space consumed. Also, if the file is compressed, the account is
only charged for the physical disk space used. After all directories have been
scanned, a report is generated detailing the total space consumed by each user's
files (in Mbytes) .
Each user account can b e assigned a preset disk quota amount. To do this, add
the quota limit to the description (or comment ) field of the user account. Using
User Manager, place the text #QUOTA : nnn# anywhere in this field to set a quota
limit of nnn Mbytes for this account. By default, USRQUOTA scans the
accounts on the local computer for quota information. The / DOMAIN switch
instead scans accounts on the domain for quota information. If an account is
assigned a quota, USRQUOTA reports these values and also the percentage of
the quota consumed by the user.
The / QUOTA switch restricts the report to user accounts which have assigned
quotas, that is, those accounts which contain #QUOTA : nnn# within the descrip
tion field of the user account. The / OVER switch further restricts the report to
Chapter 6: User Management Scripts 1 89
accounts whose actual disk quota exceeds the assigned quota limit for that
account.
Example
u s rquota e : \ h : \ / domain / over / quota
This command creates a report of all domain accounts that have exceeded their
assigned quota limits.
Implementation
The USRQUOTA.BAT script is based on the SKELETON.BAT script described
in Chapter 5. The MAI N procedure first checks to see if any arguments are pre
sent (line 49). If not, then the help text is displayed and the script exits.
If arguments are present, the PARSECMD L I N E procedure in _MTPLIB.BAT is called
(line 53) to parse the command line, and the number of positional arguments is
then checked (it must be 1 or more). The command line is then processed. The
variable QUOTASW is set to 1 if the / QUOTA switch is present (lines 55 and 56), and
the variable OVERSW is set to 1 if the / OVER switch is present (lines 59 and 60).
The DOMA I N SW variable is either empty (the default) or set to / DOMA I N if the
/ DOMA I N switch is present (lines 57 and 5 8 ) . This switch is passed to the NET
USER command when extracting user quota limits.
To tabulate the results and generate the report, the TEMPALL file is filtered by
the SORT command (line 84). This command groups together all lines that refer
to the same account. The output of the SORT command is then processed by a
FOR command, which parses each line into the domain name, user name, and
disk charge. The FOR command calls the ADDQUOTA procedure for each line
parsed.
The ADDQUOTA procedure (line 99) accumulates the results for each user account.
The current user account being accumulated is tracked in the USERNAME variable.
As soon as the USERNAME value is different from the user name argument,
ADDQUOTA emits a report record for the user account and then resets the counters
for the next account (lines 1 0 1 to 105). The actual report record is generated
by the SHOWUSERI NFO procedure, which is called by the ADDQUOTA procedure.
SHOWUSERINFO is also called after the FOR command finishes, in order to display
the results for the last account.
The ADDQUOTA procedure is passed two arguments. The first consists of the
domain name and account name combined using a backslash separator. The
second is the disk charge in bytes. ADDQUOTA simply accumulates the disk charge
in the MBTOTAL variable (line 1 06), after converting the charge value from bytes
to Mbytes.
Converting each individual total to Mbytes rather than accumulating the exact
byte count introduces slight rounding errors, but these are very slight, and con
verting early avoids any possibility of counter overflow for very large quota
charge values.
The SHOWUSERI NFO procedure actually generates the report line. The procedure
has access to the user name in the USERNAME variable and the total disk charge
for that user in the MBTOTAL variable. The procedure must now look up the disk
quota limit in the user account database:
1. The USERNAME is parsed using a FOR command ( line 123) to extract the user
name only (the domain name and user name are separated in USERNAME by
a backslash) .
2. The extracted user name i s then used to execute a NET USER command
(line 124), which generates a report on the user account specified (the
DOMAI NSW is also used here, in order to fetch the account information from
the domain if required).
3. The output of the NET USER command is filtered by a FIND command (line
124), which filters lines containing the text #QUOTA : . This command iso
lates the quota information in the NET USER output.
Chapter 6: User Management Scripts 191
4. The filter results are passed to another FOR command (line 124 ), which
captures the entire line into the MBQUOTA variable.
After the FOR command completes, the MBQUOTA variable is either empty (no
quota is assigned to this account), or it contains the description line including
the #QUOTA text. Two additional FOR commands (lines 125 and 126) are used to
parse the MBQUOTA text and extract the quota amount. First, the field is parsed
for the " #QUOTA : nnn# text, using # as a separator. Then, the result of this parse
is re-parsed to isolate the nnn amount.
The final result of this parsing is that the MBQUOTA field either contains the
quota limit for the account (in Mbytes) or is empty if the user account does not
specify a quota limit. If the quota limit is not empty, the PERCENT variable is
computed as the ratio ( MBTOTAL* 1 00 ) /MBQUOTA, which is the amount of disk
charge used as a percentage of the user quota (line 127).
Next, the SHOWUSER I NFO procedure checks the display criteria. If there is no user
quota limit ( MBQUOTA is empty) and the / QUOTA switch is specified, then SHOWUSER .
INFO exits, as this account is not a candidate for reporting (line 1 3 1 ) . Next, if
there is a user quota limit, and the percentage computed is less than or equal to
1 00, and the / OVER switch is specified, then SHOWUSERI NFO exits, as this account
is not over its quota limit and is not a candidate for reporting (line 132).
Finally, SHOWUSERINFO formats the computed quota information for tabular dis
play. Each of the variables USERNAME, MBTOTAL, MBQUOTA and PERCENT are assigned
to a temporary variable using a SET command which has been padded to the
end of the line with spaces (lines 1 3 7 to 140). Then, each variable is re
assigned to itself using string indexing to limit the length of the variable to the
width of each field in the report (lines 143 to 146). By first padding the vari
able with spaces and then truncating it to a fixed width, a tabular report is
generated. Notice the unusual lines where (for example) the USERNAME variable is
assigned to the T1 variable:
set T1 =%USERNAME%
Although not obvious from the printed copy, the SET command is padded after
the last percent sign with spaces all the way to the end of the line. This is
important, as these spaces contribute to the contents of the T1 variable. Then,
the T1 variable is assigned to itself, as follows:
set T1 =%T1 : -0 , 30%
This SET command (which is not space padded) assigns the T1 variable with the
first 30 characters of itself. In other words, the T1 variable is truncated to 30
characters or less. Since the first SET command added sufficient spaces to T1
such that it is always greater than 30 characters, the T1 variable now contains
exactly 30 characters and is comprised of the contents of the USERNAME variable
1 92 Part II: Real-World Scripting
plus extra spaces to pad it to a width of 30. This is how the fixed column
report is generated by SHOWUSERINFO.
045 . rem
046 . : MAIN
047 . if defined TRACE %TRACE% [ proc %0 %* ]
048 . rem If no argument s , we default to displaying help
049 . if {%1 }== { } ( call : HELP ) & ( goto : EOF)
050 .
05 1 . rem Parse command line and setup va riables
052 . set CMDLINE=\*
053 . call _mtplib : PARSECMDLINE 0
054 . if %CMDARGCOUNT% LSS 1 ( call : HELP ) & ( goto : EOF)
055 . call _mtplib : FINDSWITCH / quota
056 . if not " %RET% " == " 0 " ( set QUOTASW=1 ) else ( set QUOTASW=0 )
057 . call _mt plib : F INDSWITCH / domain
058 . if not " %RET% " == " 0 ' ( set DOMAINSW= / DOMAIN ) else ( set DOMAINSW= )
059 . call _mt plib : FI NDSWITCH / over
060 . if not " %RET% " == ' 0 " ( set OVERSW=1 ) else ( set OVERSW=0 )
061 .
062 . rem Get temporary f ilenames
063 . call _mtplib : GETTEMPNAME
064 . set TEMPALL=%RET%
065 . call _mtplib : GETTEMPNAME
066 . set TEMPONE=%RET%
067 .
068 . rem Accumulate disk usage results into t emporary file
069 . set / a IX=1
070 . : DISKUSELOOP
071 . call _mtplib : GETARG %IX%
072 . if " %RET% " == ' " goto : DISKUSELOOPEND
073 . set / a IX+=1
074 . if exist " %TEMPONE% " del ' %TEMPONE%"
075 . diskuse " %RET% " / T IS / F : %TEMPONE% >nul
076 . type %TEMPONE% : f ind " , ' » " %TEMPALL% '
077 . goto : DISKUSELOOP
078 . : DISKUSELOOPEND
079 .
080 . rem Now parse the results file
081 . set USERNAME=
082 . echo Username Used Quota Percent
- · - · - · · · · · · · · · · · · · · · · · · · · · · · · ·
083 . echo
084 . for / f " tokens=1 · 3 delims= , " %\I in ( ' type %TEMPALL% · : sort ' ) do call
: ADDQUOTA %\I \%%..1 %\K
085 . call : SHOWUSERINFO
086 .
087 . rem Delete t emporary f iles
088 . del %TEMPALL%
089 . del %TEMPONE%
090 . goto : EOF
091 .
092 . rem / l l l l l l l l / / l l l l l l l l l l l l l l l l l l / l l l l l / l l l / / l l l l l l l l l l l l l l l l / l l l l l l l l l l l l
194 Part II: Real-World Scripting
1 40 . set T4=%PERCENT%%%
141 .
1 42 . rem Do not pad these SET commands
1 43 . set T1 =%T1 : -0 , 30%
1 44 . set T2=%T2 : -0 , 8%
1 45 . set T3=%T3 : -0 , 8%
1 46 . set T4=%T4 : -0 , 8%
1 47 . echo %T1 % %T2% %T3% %T4% %T5%
1 48 . goto : EOF
1 49 .
1 50 . rem / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
1 51 . rem Additional procedu res g o here . . .
1 52 .
1 53 . rem These must be the F INAL LINES in the script . . .
1 54 . : DOSEXIT
1 55 . echo This script requires Windows NT
1 56 .
1 57 . rem / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
Syntax
PJCOUNT [ computer ]
Description
The PJCOUNT script analyzes the system event log on the specified computer
(or the local computer if none is specified) and generates a report showing all
print activity for each user. The report includes the number of j obs printed, the
number of pages printed, and the number of bytes sent to the printer for each
user.
196 Part II: Real-World Scripting
The DUMPEL output format was altered between the initial release of the
resource kit and the Supplement 2 release. This script requires the version
of DUMPEL that ships with Supplement 2 or later.
Windows 95 clients do not provide page count information, so the page count
is only accurate if all the clients are Windows NT computers.
Example
pj count SOCRATES
Implementation
The PJCOUNT.BAT script is based on the SKELETON.BAT script described in
Chapter 5. The core of the PJCOUNT script is a DUMPEL command (line 42).
The output of this command is analyzed and a report is generated based upon
this analysis.
In the MAIN procedure, if a computer name is specified as the (only) argument,
the COMPUTER variable is set to the text / S plus the name of the computer (line
3 8 ) . Otherwise, the COMPUTER variable is left empty. This provides the required
computer name switch for the DUMPEL [ RKJ command.
The script then executes a DUMPEL command (line 42), passing switches to filter
the system event log for print jobs only. The COMPUTER variable is passed as an
argument, so that DUMPEL analyzes the event log on the required computer. The
DUMPEL output is formatted so that it contains only the user name and print
description string. This output is passed to the SORT command to be sorted by
user name. Finally, each line of sorted output is passed to the SCANJOB procedure.
The SCANJOB procedure (line 53) analyzes each print job. As with the ADDQUOTA
procedure of the USRQUOTA script (see the previous section in this chapter),
the SCANJ OB procedure accumulates results for each user account and then out
puts a report for each user by calling the SHOWUSER INFO procedure. Results are
accumulated in the J OBCOUNT, PAGECOUNT, and BYTECOUNT variables.
Unfortunately, the output of the DUMPEL command cannot easily be split into
fields (one reason is that the name of the file printed is not quoted, and so can
not be distinguished syntactically in the report). Therefore, SCANJOB analyzes the
line (which is passed as a set of arguments to SCANJOB ) for keyword informa
tion. SCANJOB loops, processing each argument until it locates a keyword. It
then uses the keyword to extract the required information.
Chapter 6: User Management Scripts 197
For example, the number of bytes in a print job is always preceded by the key
word b y t e s : . Therefore, as soon as SCANJOB sees the b yt e s : keyword, it extracts
the byte count from the next argument.
The SHOWUSERI NFO procedure actually generates a line in the print job report.
The operation of this procedure is similar to the identically named procedure
in the USRQUOTA script, and it uses the same techniques to generate a tabu
lar report.
087 . rem The following SET commands are all space - padded to here - - - - - - - >
088 . set T1 =%USERNAME%
089 . set T2=%J08COUNT%
090 . set T3=%PAGECOUNT%
091 . set T4=%BYTECOUNT%
092 .
093 . rem Do not pad these SET commands
094 . set T1 =%T1 : -0 , 30%
095 . set T2=%T2 : -0 , 8%
096 . set T3=%T3 : -0 , 8%
097 , set T4=%T4 : -0 , 1 2%
098 . echo %T1 % %T2% %T3% %T4%
099 . goto : EOF
1 00 .
101 . rem / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
1 02 . rem Add it ional procedures g o here . . .
1 03 .
1 04 . rem These must be the FINAL LINES in the sc ript . . .
1 05 . : DOSEXIT
1 06 . echo This sc ript requires Windows NT
1 07 .
1 08 . rem / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
Implementation
The MTPLOGON.BAT script illustrates many of the typical actions performed
by a logon script, and has been structured to allow easy modification to suit
local system requirements. The script performs the following actions:
200 Part II: Real-World Scripting
1 . Sets the local computer dock from a timeserver computer. This ensures
that all computers are correctly synchronized, which is important for
some shared file applications that use timestamps to compare file versions.
2. Maps a global share to a local drive letter for all users.
3. Maps one or more "group" shares depending upon the user's group
membership.
4. Maps the user's home directory to a local drive letter.
5. Executes special per-user and per-machine logon script extensions.
6. Dumps debug information to a trace file.
The logon script is also self-installing. Executing the script from the command
line with the / INSTALL switch installs the script into a target directory on a tar
get network share. Typically, the target is the \WINNT\SYSTEM32\REPL
\EXPORT\SCRIPTS directory or the IMPORT\SCRIPTS directory if replication
is not being used.
Customization
The logon script operation can be customized by altering the following vari
ables, which are set at the start of the script:
INSTALLSHARE Target share to use when installing the logon script, in
\ \ server\ share format.
INSTALLDIR Target directory to use when installing the logon script, relative
to the INSTALLSHARE share.
DUMP FILE The full path name of the file used to hold logon script dump
information, or (if empty) to suppress dump file output.
TIMESERVER The name of the server used for time synchronization, in
\ \server format.
GLOBALDRIVE The drive letter used when mapping the global ( all users) net
work share, followed by a colon.
GLOBALSHARE The name of the global (all users) share, in \ \server \share for
mat.
GROUPDRIVE The drive letter used when mapping a group network share,
followed by a colon.
GROUPSERVER The server name containing the group shares, in \ \ server for
mat.
GROUPn Up to four group names, which are used for group mapping.
HOMEDR IVE The drive letter used when mapping the home directory, fol
lowed by a colon.
A single global share is mapped in the sample script (lines 44 to 49), though
obviously others can be added as needed. The GLOBALSHARE specifies the share
name, and the GLOBALDR IVE specifies the local drive to map.
Up to four group shares are also mapped by the sample script. Group share
mapping relies upon the I FMEMBER command, which only operates under
Windows NT. Therefore, the script does not attempt group share mapping if
the operating system on the client is not Windows NT. Membership in each
group is checked using the I FMEMBER command. If the user account is a member
of the group, the GROUPDR IVE drive letter is mapped to the appropriate GROUP
share on the GROUPSERVER server. This sample code assumes that the name of the
share on the server is the same as the name of the group.
The final drive mapping performed by the sample script maps the user's home
directory to the HOMEDRIVE drive letter (lines 8 1 to 86).
After all drives are mapped, the logon script checks to see if two additional
scripts exist, and executes them if they are present. First, drive C: is checked for
an additional script named MTPLOGON.BAT in the root (line 89). If this is
present, it is executed. Next, drive U: (the user home directory drive) is checked
in the same manner (line 93). The drive C: script can provide "per-machine"
initialization; that is, initialization unique to a particular computer, but inde
pendent of the user. The drive U: script can provide "per-user" initialization;
that is, initialization unique to the user but independent of the machine.
The final action performed by the logon script creates a dummy file called
lmscript.$$$ in the C:\WINDOWS or C:\WIN95 directory. This is a bug fix
that is recommended by Microsoft to correct certain problems associated with
Windows 3.x and Windows 95 clients. These clients can fail to recognize the
end of logon script execution under certain conditions. Creating this dummy
file corrects this condition.
After the logon script is complete, the script generates a dump file containing a
report of all current network drive mappings and the current user environment.
This can be useful when debugging logon script problems.
060 . : NOGROUP1
061 . if " %GROUP2% " == " " goto NOGROUP2
062 . ifmember %GROUP2%
063 . if not erro rlevel 1 goto NOGROUP2
064 . echo . . . Map %GROUPOR IVE% to %GROUPSERVER%\%GROUP2%
065 . net use %GROUPDR IVE% %GROUPSERVER%\%GROUP2% %NETSW%
066 . : NOGROUP2
067 . if " %GROUP3% " == " " goto NOGROUP3
068 . ifmember %GROUP3%
069 . if not erro rlevel 1 goto NOGROUP3
070 . echo · · · Map %GROUPDR IVE% to %GROUPSERVER%\%GROUP3%
071 . net use %GROUPDR IVE% %GROUPSERVER%\%GROUP3% %NETSW%
072 . : NOGROUP3
073 . if " %GROUP4% " == " " goto NOGROUP4
074 . ifmember %GROUP4%
075 . if not erro rlevel 1 goto NOGROUP4
076 . echo · · · Map %GROUPDR IVE% to %GROUPSERVER%\%GROUP4%
077 . net use %GROUPDRIVE% %GROUPSERVER%\%GROUP4% %NETSW%
078 . : NOGROUP4
079 . : NOGROUPS
080 .
081 . rem Map users home directory
082 . if " %HOMEDR IVE% " == " " goto NOHOME
083 . echo - - - Map %HOMEDR IVE% to home directory
084 . if exist %HOMEDR IVE%* . * net use %HOMEDR IVE% / delete
085 . net use %HOMEDR IVE% / home %NETSW%
086 . : NOHOME
087 .
088 . rem Execute logon script extensions
089 . if not exist c : \ mt plogon . bat goto NOTCEXT
090 . echo - - - Execute machine - specific logon extension
091 . call c : \ mtplogon . bat
092 . : NOTCEXT
093 . if not exist u : \ mtplogon . bat goto NOTUEXT
094 . echo - - - Execute user - specific logon extension
095 . call u : \ mtplogon . bat
096 . : NOTUEXT
097 .
098 . rem Special fix for Windows logon sc ript end bugs
099 . if exist c : \windows \ * . * echo . >c : \windows \ lmscript . $$$
1 00 . if exist c : \win95 \ * . * echo . >c : \windows \ lmscript . $$$
101 .
1 02 . rem End of logon sc ript
1 03 . echo . . . LOGON SCRI PT END $Revision : 2 $ . . .
1 04 . if not " %DUMPFILE% " == " " net use >%DUMPFI LE%
1 05 . if not " %DUMPFILE% " == " " set »%DUMPFI LE%
1 06 . u:
• UNCBACK script
This script adds UNC filename support to the Windows NT backup
application.
• XCPTEST script
This script can provide a thorough machine test/bum-in to validate new
hardware.
• REPL script
The most complete sample script in the book, this script provides a com
plete peer-to-peer file replication facility.
• ANIMAL script
To close this part of the book, a classic computer game is implemented as
a script.
The sample scripts in this chapter are available for downloading from the
MTP web site at http://www.macmillantech.com.
Syntax
UNCBACK [ dir -list ] [ switches ]
Description
The UNCBACK script executes an NTBACKUP backup command. The dir - l i s t
argument is one or more directory names to back up, separated by spaces.
Following dir -list are zero or more switches. These switches are passed,
unedited, to the NTBACKUP command. Thus, any valid NTBACKUP switch can be
placed on the command line of UNCBACK.
In addition, any switches placed in the NTBACKUPSW variable are also passed to
the NTBACKUP command. These switches (if any) are inserted in the command
before any switches placed on the UNCBACK command line.
Items in the dir - l i s t can be either local or mapped network drives, or UNC
names (in the form \\server\share). If the directory name is a UNC name, the
share is temporarily mapped to a drive letter for the duration of the backup
operation.
Example
uncback c : \ d : \ \ \ PLX1 4 \ Users / hc : on / v
This example backs up the local drives C: and D:, and the network share
\\PLX14\Users. The / HC : ON and / V switches are passed to the NTBACKUP com
mand, thus enabling hardware compression and verifying the backup.
Implementation
The UNCBACK.BAT script is based on the SKELETON.BAT script described
in Chapter 5. The MAIN procedure first checks to see if any arguments are pre
sent (line 5 1 ) . If not, then the help text is displayed and the script exits.
Chapter 7: Miscellaneous Scripts 207
If one or more arguments are present, the command line is parsed. The com
mand line is comprised of two parts: the dir - list directory list, followed by
any switches. First, all directory names in the dir-list are placed in the PATH
LIST variable {liens 59 to 72). Each directory name is placed in double quotes,
and they are separated from each other by spaces. This processing is performed
by the loop beginning at the : PATHLISTLOOP label. The loop ends when either all
arguments have been processed, or the first switch (an argument that begins
with a I or - character) is encountered.
Individual directory names are processed as follows: First, surrounding double
quotes (if any) are removed (line 62). Then, the first two characters of the
name are checked. If they are \ \ , the name is assumed to be a UNC name (line
65 ). If a UNC name is encountered, the following commands are executed:
1 . pushd " %T 1 % "
2 . s e t / a UNCCOUNT+=1
3. for / f " token s=* " %%! in ( ' cd ' ) do set T1 =%%!
Since the PUSHD command is passed a UNC name, it automatically maps the
UNC name to a drive letter. Using PUSHD is superior to the NET USE command
for this purpose, as PUSHD automatically assigns drive letters, choosing unused
letters. The variable UNCCOUNT is then incremented, which tracks the number of
UNC names that have been assigned using the PUSHD command.
The script now needs to discover which drive letter was mapped by the PUSHD
command, so this can be passed to the NTBACKUP command instead of the UNC
name. To do this, a CD command is executed with no arguments {which there
fore displays the current drive and directory). This output is captured by a FOR
command and placed in the T1 variable. Thus, the lines shown above start with
a UNC name in the variable T1 , and end with an equivalent mapped drive let
ter and path in T1 instead. Therefore, when the T1 variable is added to the
PATHLIST variable, a mapped drive letter replaces the UNC name.
After the directory names are accumulated, a similar loop (beginning at the
: SWITCHLISTLOOP label, line 76) builds a list of all switch arguments. These are
placed, separated by spaces, in the SWITCHLIST variable.
Once all command arguments have been processed, the NTBACKUP command is
executed (line 85). The command is passed the PATHLIST, NTBACKUPSW, and
SWITCHLIST variables as arguments. This constructs the required NTBACKUP
command.
After NTBACKUP completes, the temporary drive mappings assigned by the
PUSHD commands must be removed. This is done by executing zero or more
POPD commands. The number of POPD commands to execute is controlled by
UNCCOUNT, and therefore a FOR iterator command (line 8 8 ) is used to execute the
required number of POPD commands.
208 Part II: Real-World Scripting
01 . @echo OFF
02 . @if not "%ECHO% " == " " echo %ECHO%
03 . @if not "%0S% " == " Windows_NT " goto DOSEXIT
04 . rem $Workfile : uncback . bat $ $Revision : 2 $ $Dat e : 1 2 / 04 / 97 9 : 5 1 a $
05 . rem $Archive : / TimH/ Pubs / Books / Macmillan / Windows NT
Scripting / Scripts / uncbac k . bat $
06 .
07 . rem Set local scope and call MAIN procedure
08 . setlocal & pushd & set RET=
09 . set SCRI PTNAME=%-n0
10. set SCRIPTPATH=%-f0
11. if " %DEBUG% " == " 1 " ( set TRACE=echo ) else ( set TRACE=rem )
12. call _mtplib : INIT %SCRIPTPATH%
13. if / i {%1 }=={ / help} ( call : HELP %2 ) & ( goto : HELPEXIT)
14. if / i {%1 }=={ / ? } ( call : HELP %2 ) & ( goto : HELPEXIT)
15. call : MAIN %*
16. : HELPEXIT
17. popd & endlocal & set RET=%RET%
18. goto : EOF
19.
20 . rem / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
21 . rem HELP procedure
22 . rem Display b rief on - line help message
23 . rem
24 . : HELP
25 . if defined TRACE %TRACE% [ proc %0 %* ]
26 . echo Syntax : UNCBACK [ dir - list ] [ switches ]
27 . echo I nvokes NTBACKUP for the specified dir - list .
28 . echo .
29 . echo All switches at the end of the command line are passed unaltered to
30 . echo NTBACKUP . The contents of the NTBACKUPSW variable is prefixed before
31 . echo these switches .
32 . echo .
33 . echo Directory names in the dir - list can be UNC names , which are mapped
34 . echo to d rive letters for the du ration of the backup operation .
35 . echo .
36 . echo Example :
37 . echo UNCBACK C : \ D : \ \ \ SERVER \ F I LES1 /A / B JV
38 . goto : EOF
39 .
40 .
41 . rem / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
42 . rem MAIN procedure
43 . rem
44 . rem Arguments : pat h ( s ) =path names to backup ( incl . UNC names )
45 . rem / . . . =first switch marks start of switches passed to NTBACKUP
46 . rem NTBACKUPSW=additional switches passed before cmdline ones
47 . rem
48 . : MAIN
49 . if defined TRACE %TRACE% [ proc %0 %* ]
Chapter 7: Miscellaneous Scripts 209
Syntax
XCPTEST re f - di r tes t - di r [ . . . ] ( / PASSES : n ] [ / CHECK : m ] [ / NOSTOP ] [ / NOCONFIRM]
Switches
/ PASSES : n Sets the number of test passes to perform to n (the default is
infinite) .
/CHECK : m Sets the pass count between file integrity checks (the default i s 10).
/ NOSTOP Don't stop o n a file copy error.
/ NOCON F I RM Skips the confirmation before erasing the test directory contents.
Description
The XCPTEST script provides a simple burn-in (or soak test) for computers
running Windows NT. XCPTEST can frequently detect hardware errors that go
undetected by other testing methods.
XCPTEST works by copying a set of files from one directory to another in
round-robin fashion. That is, if three directories, A, B and C, are specified, the
test copies from A to B, then B to C and finally from C to A. This constitutes a
single "pass" by the test loop.
By default, XCPTEST executes an infinite number of passes. The / PASSES
switch limits the number of passes to n. In addition, the test prompts with a
Continue? request at the end of each pass. If no response is entered within five
seconds, testing continues. This allows the test to run unattended, but to be
interrupted gracefully.
The set of files to copy is obtained from a known good source, the ref - dir. A
good source for the ref - dir is a CD-ROM. To ensure accurate testing, make
Chapter 7: Miscellaneous Scripts 211
sure that the total size o f all the files i n the ref- dir is larger than the amount of
physical memory present in the machine under test. Sub-directories of the ref
dir are not included in the set of test files. A good choice for ref - dir is the
\13 86 directory on the Windows NT distribution CD-ROM.
The test directories are specified on the command line following ref - dir. If
only one tes t - dir is specified, XCPTEST creates two sub-directories within this
directory, called TESTl and TEST2, and uses these for copying the files back
and forth. If more than one tes t - dir is specified, the named directories are
used for file copying. Any number of test directories can be specified, in any
valid location. Local drives and network drives can be used, and UNC names
are allowed except for the first tes t - dir.
The test directories are created if they do not already exist. If they do already
exist, all files in the directories are deleted. Therefore, take great care when
choosing test directories. Unless the / NOCONFIRM switch is used, the script
prompts for confirmation before deleting the test directories.
Gross hardware errors that occur during testing usually manifest themselves as
system hangs or Windows NT STOP screens. More subtle hardware errors typ
ically result in corruption of the file data copied by the test. To check for this
corruption, XCPTEST periodically verifies the contents of the test directories
against the reference directory. By default, the file contents are checked every
10 passes, and once again before the test finally terminates. The / CHECK switch
changes the number of passes between file verification checks. If the checking
detects a file corruption, the test terminates with an error. The / NOSTOP switch
over-rides this behavior, and allows testing to continue regardless of the num
ber of errors which occur.
In addition to hardware testing, XCPTEST can be used to stress-test networks
and disk sub-systems. Running multiple copies of XCPTEST (using separate
sets of test directories) can also exercise SMP (that is, multi-CPU) systems quite
effectively.
Example
xcptest g : \ i386 c : \ test d : \test f : \ test / nostop
This example obtains test files from the G:\13 86 directory. The files are then
copied between the directories C:\TEST, D:\TEST and F:\TEST repeatedly. The
/ NOSTOP switch stops the test from terminating on an error.
Implementation
The MAKEUSR.BAT script is based on the SKELETON.BAT script described
in Chapter 5. The MAI N procedure first checks to see if any arguments are pre
sent. If not, then the help text is displayed and the script exits.
212 Part II: Real-World Scripting
processes each argument (directory) in a loop. If the directory exists, all files
are deleted. If it does not exist, it is created.
The COPYREFDI R procedure is a wrapper for an XCOPY command, which copies
the contents of the reference directory into the first test directory.
The COPYDIRLIST procedure provides the actual round robin file copying. Like
DELETETESTDIRS, it is passed the DIRLIST variable and so receives the list of test
directories as arguments. The procedure enters a loop at the COPYDIRLISTLOOP
label until there are fewer than two arguments remaining. For each pass of the
loop, an XCOPY command copies one test directory to the next. Finally, an addi
tional XCOPY command copies the last directory in the list back to the first, com
pleting the round robin loop.
The CHECKDIR procedure verifies the integrity of the test files against the refer
ence directory. The core of this procedure is an FC / B command that compares
all reference directory files to those in the first test directory. The FC command
does not return a valid exit code, and so the report output produced by the
command is analyzed for errors. The output of the FC command is passed to a
FIND command, which removes all lines containing the text Comparing. The out
put of this FIND command is then passed to another F I ND which removes all
lines containing FC : no. After these two filter commands, the residual output
consists of empty lines and error lines. The output is then captured by a FOR
command and parsed. The FOR command filters all blank lines, leaving only
lines containing errors. The ERRORS counter is then incremented for each of
these lines.
01 9 .
020 . rem / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
021 . rem HELP procedure
022 . rem Display brief on - line help message
023 . rem
024 . : HELP
025 . if defined TRACE %TRACE% [ p roc %0 %* )
026 . echo Syntax : XCPTEST ref - d i r test - dir [ . . . ] / PASSES : n / CHECK : m
027 . echo Ping - pong XCOPY machine soak test .
028 . echo .
029 . echo Copies a reference directory in round - robin fashion among
030 . echo two or more test dirs , checking for file corruption or loss .
031 . echo .
032 . echo The source dir is ref - dir . If two or more test - dirs are
033 . echo specified , these are used round - robin . If one test - d i r is
034 . echo specified , two sub - dirs ( test1 and test2 ) are used in this
035 . echo test -dir . ALL FI LES IN THE TEST DIRECTORIES ARE DELETED ! ! !
036 . echo .
037 . echo Use / PASSES to specify the number of passes ( def : infinite ) .
038 . echo Use /CHECK to specify pass counts between each file check .
039 . echo ( def : 1 0 ) . Use / NOSTOP to prevent test stopping on e r ro r ( s ) .
040 . goto : EOF
041 .
042 . rem / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
043 . rem MAIN procedure
044 . rem
045 . : MAIN
046 . if defined TRACE %TRACE% [ p roc %0 %* )
047 . rem If no arguments , we default to displaying help
048 . if {%1 } == { } ( call : HELP ) & ( goto : EOF )
049 .
050 . rem Parse command line and setup variables
051 . set CMDL INE=%*
052 . call _mtplib : PARSECMDLINE 0
053 . if %CMDARGCOUNT% LSS 2 ( call : HELP ) & ( goto : EOF)
054 . call _mt plib : FINDSWITCH / passes
055 . if " %RET% " == " 0 " ( set / a PASSES=0 ) else ( set / a PASSES=RETV )
056 . call _mt plib : FINDSWITCH / check
057 . if ' %RET% ' == " 0 " ( set / a CHECKEVERY=1 0 ) else ( set / a CHECKEVERY=RETV )
058 . call _mt plib : F INDSWITCH / nostop
059 . if " %RET% ' == " 0 " ( set / a NOSTOP=0 ) else ( set / a NOSTOP= 1 )
060 . call _mtplib : F INDSWITCH / y
061 . if "%RET% ' == " 0 " ( set NOCONFIRM=0 ) else ( set NOCONFI RM= 1 )
062 . call _mtplib : GETARG 1
063 . set REFDIR= " %RET% "
064 . if %CMDARGCOUNT% GTR 2 goto : USERLIST
065 . call _mtplib : GETARG 2
066 . set DIRLIST= " %RET%\ test1 . " %RET%\ test2 "
067 . goto : DIRLISTDONE
068 . : USERL IST
069 . set DIRLIST=
Chapter 7: Miscellaneous Scripts 215
1 71 . goto : COPYDIRLISTLOOP
1 72 . : COPYDIRLISTLOOPEND
1 73 . xcopy \1 \FIRST\ / r/ q
1 74 . goto : EOF
1 75 .
1 76 . rem / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
1 77 . rem Additional proced u res go here . . .
1 78 .
1 79 . rem These must be the FINAL LINES i n the script • • .
1 80 , : DOSEXIT
1 81 . echo This script requires Windows NT
1 82 .
1 83 . rem / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
Syntax
1 . REPL [ site - name ]
2 . REPL site - name ( /ADD : dir . . . ] ( / DELETE : dir . . . ]
3 . REPL site - name / DELALL [ / Y I
4 . REPL site - name ( / ENABLE : / DISABLE ]
5 . REPL / RESET ( /Y ]
6 . REPL / START ( / INTERVAL : nn n ] ( / FIRST : nnn] [ / LOG : l og - file ]
7 . REPL / STOP
8 . REPL / RUN [ / LOG : log - fil e ]
Switches
/ADD : dir Adds a directory to a replication site.
/ DELETE : di r Deletes a directory from a replication site.
/ DE LALL Deletes all directories from a replication site.
218 Part II: Real-World Scripting
Description
The REPL script provides a general-purpose file and directory replication facili
ty for Windows NT. Unlike the Windows NT replication service, all replication
directories managed by REPL are "peers." That is, there are no "master" and
"slave" (or export/import) directories. Instead, REPL treats all directories as
export and import directories.
REPL manages sets of directories known as sites. A site is a set of one or more
directory .trees that are to be synchronized by the REPL facility. Sites are given
arbitrary names to identify them, and REPL can support any number of sites,
each containing any number of directories. Directories can be specified as local
drive paths or UNC names. For example, a site named SAMPLE could contain
the directories C:\Source, E:\Users\Source and \\LIBRARY\Archive\Source.
When REPL updates the SAMPLE site, all the directories are synchronized so
that the contents of each tree are identical. The full directory trees are synchro
nized, including all sub-directories.
Using UNC names for directories is recommended. REPL can perform replica
tion runs with no user logged-in. In this case, networked drives may not be
mapped as expected, and the replication can fail. Using UNC names avoids this
problem, as the name is always valid, regardless of user logon state.
REPL synchronizes the directories within a site by performing a round robin
copy of files from one directory tree to the next. Thus, if a site contains three
directories, A, B, and C, the REPL script copies directory A to B, then B to C,
and then C back to A. In this way, a file placed in any of the directories A, B
or C will eventually be propagated to all three directories (although it can take
up to two replication passes to complete the copy).
Chapter 7: Miscellaneous Scripts 219
Example
repl Scripts / add : c : \Scripts / add : e : \ SrcSaf e \ Sc ripts / add : \ \
SRV - USERS \ Users \TimH \ Scripts / enable
This example adds three directories to the Scripts site and enables the site. The
Scripts site is created if it does not already exist.
repl / start / interval : 30 / log : c : \ repl . log
Imp lementation
The REPL.BAT script is based on the SKELETON.BAT script described in
Chapter 5. All state and site information managed by REPL is maintained in
the registry in the HKEY_LOCAL_MACHINE key (this key is used so that the
information is available when REPL executes under the control of the
Scheduler service). REPL functionality can be broken into two parts:
• The interactive functions that edit the state information
• The actual replication functions that interpret the state information.
Replication state information for a site is maintained in the variable
RSENABLE_si tename and the array RSDI R_si tename_n_, where n is the array index.
This information is moved to and from the registry using the LOADREG and
SAVEREG procedures, which are wrappers for the REGSETM and REGGETM procedures
in _MTPLIB.BAT. These procedures load the state information for all sites at
once. To simplify coding, one specific site is designated as the working site. The
working site is maintained in the variables WORKENABLE, WORKDI R_n_ and
WORKCOUNT. The procedures LOADSITE and SAVESITE move state information in the
site variables to/from the working site variables. Therefore, to edit a site, the
following operations must be performed:
1 . Load the state information from the registry using LOADREG.
2. Load the required site to the working site using LOADSITE.
3. Edit the working site.
4. Save the working site back into the site variables.
5. Save all site variables in the registry.
The SAVESITE procedure also provides a packing function. When the working
site is edited, one or more directories can be deleted. Deletions are processed
by deleting entries in the WORKDIR_n_ array. Thus, this array can have "holes"
when SAVESITE is called. The procedure therefore re-packs the site before it is
saved back to the site variables.
Chapter 7: Miscellaneous Scripts 22 1
The MAI N procedure begins by parsing the command line using the PARSECMDLINE
procedure from the _MTPLIB.BAT script library (line 59). The variable SITE
NAME is then set to the first positional argument (line 63 ). Then, depending
upon the command-line switches, MAI N dispatches (lines 66 to 76) to a handler
routine as follows:
1 . If no switches are present, REPLSHOW is called to display the current replica
tion status.
2. If the / RESET switch is found, REPLRESET is called to reset (clear) all replica
tion sites.
3. If the / START switch is found, REPLSTART is called to start automatic
replication.
4. If the / STOP switch is found, REPLSTOP is called to stop automatic
replication.
5. If the / RUN switch is found, REPLRUN is called to perform a single replica
tion run.
6. REPLEDIT is called to handle all other switches and edit the site
information.
The REPLSHOW procedure (line 85) displays site information. The registry infor
mation is loaded using LOADREG, and REPLSHOW1 is called to display information
on each site. If a site - name is present on the command line, REPLSHOW1 is called
once for this site (line 89). Otherwise, a FOR command (line 90) is used to iter
ate all sites, and REPLSHOW1 is called for each site. Finally, the current automatic
replication state is displayed.
REPLSHOW1 displays the details for a specified site. The site is loaded using LOAD
SITE (line 1 04), and then the list of directories replicated by the site is dis
played, along with the enabled state of the site.
The REPLRESET procedure (line 1 1 8 ) resets all replication sites. After confirming
this operation with the user, the procedure simply deletes the entire replication
registry state (line 127). This resets all replication information.
The REPLSTART procedure (line 1 39) starts automatic replication, while the
REPLSTOP replication stops automatic replication. Automatic replication is
actually initiated by the Windows NT schedule service. An AT command is sub
mitted which executes a REPL / RUN command. Additional switches to the REPL
command cause an additional REPL / RUN command to be submitted for later
execution. This ensures that REPL executes regularly at the specified interval.
REPLSTART begins by disabling any existing automatic replication. It calls GETRE
PLJOB I D (line 141 ) to get the schedule service job ID of any REPL.BAT
222 Part II: Real-World Scripting
command. This command is then deleted using the AT / DELETE command (line
143 ) . A new schedule service command is then constructed using the command
line switches, and this is then passed to the SOON [ RK J command (line 1 6 1 ),
which schedules the command for later execution.
The REPLRUN procedure (line 1 87) performs the actual replication. Before start
ing any replication work, REPLRUN regenerates a new schedule service command
and submits it via the SOON command (line 200 ). This only occurs if the current
run request is an automatic run (indicated by the presence of the / INTERVAL
switch) . Each time an automatic replication operation is run, the next periodic
command is re-scheduled to start after the appropriate interval. The interval
value is passed from command to command using the I INTERVAL switch.
After scheduling another command, REPLRUN proceeds to perform the actual file
and directory replication. All sites are loaded via LOADREG, and the REPLRUN 1 pro
cedure (line 210) is called for each site (by iterating each variable named RSEN
ABLE_sitename } . The REPLRUN1 procedure loads the site into the working site via
the LOADSITE procedure (line 212), and then enters the REPLRUNLOOP, which
processes each directory in the directory list. Directory pairs are then passed to
the REPLRUN2 procedure (line 226), which executes the ROBOCOPY command (line
234) to replicate one directory into the next. REPLRUN1 completes by calling
REPLRUN2 one more time (line 224) , to copy the last directory in the list back to
the first, thus closing the round robin loop.
The REPLEDIT procedure (line 247) edits a site. The site is first loaded using the
LOADREG and LOADSITE procedures. Then each command switch is processed by
using a numeric iterator FOR command. Finally, the edited site is saved using the
SAVESITE and SAVEREG procedures. Each command switch invokes the appropri
ate edit procedure (for example, /ADD invokes the REPLEDITADD procedure) .
The REPLEDITADD procedure (line 275 ) adds a new directory to a site. To ensure
that duplicate directories do not exist in a site, REPLEDITADD begins by deleting
the directory from the site, and then appends the directory to the end of the
site directory list.
The REPLEDITDELETE procedure (line 282) deletes a directory from the site. The
list of directories is searched, and any matching directories are deleted by clear
ing the appropriate array entry. This leaves "holes" in the working directory
array, which must be packed by the SAVESITE procedure.
The REPLEDITDELALL procedure (line 294) deletes all directories from a site, sim
ply by deleting the entire working site.
Chapter 7: Miscellaneous Scripts 223
050 .
051 . rem / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
052 . rem MAIN procedure
053 . rem
054 . : MAIN
055 . if defined TRACE %TRACE% [ p roc %0 %* ]
056 . rem Parse command line and check for basic switches etc
057 . set CONTEXT=%SCR IPTNAME% . BAT
058 . set CMDLINE=%*
059 . call _mtplib : PARSECMDL INE 0
060 . call _mtplib : FINDSWITCH / y
061 . if "%RET% " == " 0 " ( set NOCONFIRM=0 ) else ( set NOCONFIRM=1 )
062 . call _mtplib : GETARG 1
063 . set SITENAME=%RET%
064 .
065 . rem Dispatch to handler based upon arguments and switches
066 . if "%CMDSWCOUNT% " == " 0 " ( call : REPLSHOW) & ( goto : EOF)
067 . call _mtplib : FINDSWITCH / reset
068 . if not "%RET% " == " 0 " ( call : REPLRESET ) & ( goto : EOF)
069 . call _mtplib : FINDSWITCH / start
070 . if not " %RET% " == " 0 " ( call : REPLSTART ) & ( goto : EO F )
071 . call _mtplib : FINDSWITCH / stop
072 . if not "%RET% " == " 0 " ( call : REPLSTOP ) & ( goto : EOF)
073 . call _mtplib : FINDSWITCH / run
074 . if not " %RET% " == " 0 " ( call : REPLRUN ) & ( goto : EOF )
075 . if " %SITENAME% " == " " ( echo repl : s ite name required ) & ( goto : EOF)
076 . call : REPLEDIT
077 . goto : EOF
078 .
079 . rem / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
080 . rem REPLSHOW procedu re
081 . rem Show status of one or all sites
082 . rem
083 . rem Arguments : SITENAME=name of site to display , empty for all sites
084 . rem
085 . : REPLSHOW
086 . if defined TRACE %TRACE% [ proc %0 %* ]
087 . rem Load site information and display it
088 . call : LOADREG
089 . if not "%SITENAME% " == " " ( call : REPLSHOW1 RSENABLE_%SITENAME%) & ( goto
: REPLSHOW9 )
090 . for / f " tokens=1 delims== " %%I in ( ' set RSENABLE_ 2">nul ' ) do call
: REPLSHOW1 %%I
091 . : REPLSHOW9
092 .
093 . rem Display run status
094 . call : GETREPLJOBID
095 . if " %RET% " == " NONE " (
096 . echo Replication is not running .
097 . else (
098 . echo Replication is running .
Chapter 7: Miscellaneous Scripts 225
099 .
1 00 . goto : EOF
1 01 . : REPLSHOW1
1 02 . if not defined % 1 goto : EOF
1 03 . for / f " tokens=2 delims=_" %%J in ( " %1 " ) d o set T1 =%%J
1 04 . call : LOADSITE %T1 %
1 05 . if " %WORKENABLE% " == " 1 " ( set RET=enabled ) else ( set RET=d isabled )
1 06 . echo Replicat ion site· %T1 % (%WORKCOUNT% dirs ) i s %RET% :
1 07 . for / 1 %%J in ( 1 , 1 , %WORKCOUNT%) d o call : REPLSHOW2 %%J
1 08 . goto : EOF
1 09 . : REPLSHOW2
110. set RET=%%WORKDI R_%1 _%%
111 . call _mtplib : RESOLVE
112. echo %RET%
1 13. goto : EOF
1 14.
115. rem / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
1 15. rem REPLRESET procedure
116. rem Reset ( delete ) all replication sites ( requires confirmat ion )
1 17. rem
1 18. : REPLRESET
1 19. if defined TRACE %TRACE% ( p roc %0 %* ]
1 20 . rem Confirm deletion i s ok
1 21 . if not " %NOCONFIRM% " = = " 1 " (
1 22 . %COMSPEC% J c choice J n " Delete all sites? "
1 23 . if errorlevel 2 goto : EOF
1 24 .
1 25 .
1 26 . rem Delete all registry contents for sc ript
1 27 . call _mtplib : REGDELM %CONTEXT%
1 28 . echo All sites deleted .
1 29 . goto : EOF
1 30 .
1 31 . rem / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
1 32 . rem REPLSTART procedure
1 33 . rem Sta rt automatic replication
1 34 . rem
1 35 . rem Argument s : / interval : n nn=set inte rval to nnn minutes ( def : 60 )
1 36 . rem / f irst : n nn=do f i rst run in nnn minutes ( def : 1 )
1 37 . rem / log : f ile=send o / p to log - f ile ( def : none )
1 38 . rem
1 39 . : REPLSTART
1 40 . if defined TRACE %TRACE% [ p roc %0 %* ]
1 41 . rem First , stop any current replication
1 42 . call : GETREPLJOBID
1 43 . if not " %RET% " == " NONE " at %RET% / delete
1 44 .
1 45 . rem Get logfile info
1 46 . set LOGFILE=
1 47 . set LOGCMD=
1 48 . call _mtplib : FINDSWITCH / log
226 Part II: Real-World Scripting
1 49 . if not " %RET% " == " 0 " ( set LOGFI LE=%RETV% ) & ( set LOGCMD= / log : %RETV% )
1 50 .
1 51 . rem Get values for interval and first run delay
1 52 . set / a INTERVAL=60
1 53 . call _mt plib : F INDSWITCH / int erval
1 54 . if not " %RET% " == " 0 " set / a INTERVAL=RETV
1 55 . set / a FIRST=1
1 56 . call _mtplib : FINDSWITCH / first
1 57 . if not " %RET% " == " 0 " set / a FI RST=RETV
1 58 .
1 59 . rem Schedule the first AT command via SOON
1 60 . set / a FIRST*=60
1 61 . soon %FI RST% " %COMSPEC% / c %SCRI PTPATH% / run / inte rval : %INTERVAL%
%LOGCMD% " >nul
1 62 . echo Replication started .
1 63 . goto : EOF
1 64 .
1 65 . rem / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
1 66 . rem REPLSTOP procedure
1 67 . rem Stop automatic replication
1 68 . rem
1 69 . : REPLSTOP
1 70 . if defined TRACE %TRACE% [ p roc %0 %* ]
1 71 . call : GETREPLJOBID
1 72 . if " %RET% " == " NONE " (
1 73 . echo Replication is not runn ing .
1 74 . else (
1 75 . at %RET% / delete
1 76 . echo Replication stopped .
1 77 .
1 78 . goto : EOF
1 79 .
1 80 . rem / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
1 81 . rem REPLRUN procedure
1 82 . rem Perform a replicat ion run ( may be invoked f rom AT )
1 83 . rem
1 84 . rem Argument s : / interval : n nn=set inte rval to nnn minutes ( def : 60 )
1 85 . rem / log : f ile=send o / p to log - file ( def : none)
1 86 . rem
1 87 . : REPLRUN
1 88 . if defined TRACE %TRACE% [ proc %0 %* ]
1 89 . rem Get logfile info
1 90 . set LOGFI LE=
1 91 . set LOGCMD=
1 92 . call _mt plib : F INDSWITCH / log
1 93 . if not "%RET% " == " 0 " ( set LOGFI LE=%RETV% ) & ( set LOGCMD= / log : %RETV%)
1 94 .
1 95 . rem Regenerate next run if required
1 96 . call _mtplib : FINDSWITCH / interval
1 97 . if " %RET% " == " 0 " goto : NOREGEN
1 98 . set / a INTERVAL=RETV
Chapter 7: Miscellaneous Scripts 227
1 99 . set / a RETV*=60
200 . soon %RETV\ " %COMSPEC% / C %SCRI PTPATH% / run / inte rval : %I NTERVAL%
%LOGCMD%" >nul
201 . : NOREGEN
202 .
203 . rem Load all sites and replicate them
204 . if " %LOGFILE% " == " " ( set LOGCMD=A>nul) else ( set LOGCMD= A > A >%LOGFILE%)
205 . date / t %LOGCMD%
206 . time / t %LOGCMD%
207 . call : LOADREG
208 . for / f " tokens=1 delims== " %%I in ( ' set RSENABLE_ 2A>nul ' ) do call
: REPLRUN 1 %%I
209 . goto : EOF
21 0 . : REPLRUN1
21 1 . for / f " tokens=2 delims=_" ¥aJ in ( " %1 " ) do set T1 =%%J
21 2 . call : LOADSITE %T1 %
21 3 . if %WORKENABLE%==0 goto : EOF
214. if %WORKCOUNT% LEQ 1 goto : EOF
21 5 . set / a SRCIX=1
21 6 . set / a DSTIX=2
21 7 . : REPLRUNLOOP
21 8 . if %DSTIX% GTR %WORKCOUNT% goto : REPLRUNLOOPEND
21 9 . call : REPLRUN2 %SRCIX% %DSTIX%
220 . set / a SRCIX+=1
221 . set I a DSTIX+=1
222 . goto : REPLRUNLOOP
223 . : REPLRUNLOOPEND
224 . call : REPLRUN2 %SRCIX% 1
225 . goto : EOF
226 . : REPLRUN2
227 . set RET=%!\IWORKDI R_%1 _%%
228 . call _mtplib : RESOLVE
229 . set SRC=%RET%
230 . set RET=%!\IWORKDI R_%2_%%
231 . call _mtplib : RESOLVE
232 . set DST=%RET%
233 . echo robocopy " %SRC% " " %DST% " / e %LOGCMD%
· · ·
350 . rem
351 . : LOADSITE
352 . if defined TRACE %TRACE% [ proc %0 %* ]
353 . rem Clear existing working site
354 . set / a WORKENABLE=1
355 . set / a WORKCOUNT=0
356 . call _mtplib : VARDEL WORKDIR_
357 . if not defined RSENABLE_%1 goto : EOF
358 .
359 . rem Load site into working site
360 . set / a WORKENABLE=RSENABLE_%1
361 . for / f " tokens=1 delims== " %%I in ( ' set RSDIR_%1_ 2A>nul ' ) do call
: LOADSITE1 %1 %%I
362 . goto : EOF
363 . : LOADSITE 1
364 . for / f " token s=3 delims=_ " %%J in ( " %2 " ) do set IX=%%J
365 . set RET=\%%2%%
366 . call _mtplib : RESOLVE
367 . set WORKDIR_%IX%_=%RET%
368 . set / a WORKCOUNT+=1
369 . goto : EOF
370 . .
371 . rem / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
372 . rem SAVESITE proced u re
373 . rem Save site f rom working vars , with site compaction
374 . rem
375 . rem Argument s : %1 =site name
376 . rem
377 . : SAVESITE
378 . if defined TRACE %TRACE% [ proc %0 %* ]
379 . rem Clear existing site data
380 . set RSENABLE_%1 =
381 . call _mt plib : VARDEL RSDIR_%1_
382 . if not defined WORKENA8LE goto : EOF
383 . if not defined WORKCOUNT goto : EOF
384 . if %WORKCOUNT% EQU 0 goto : EOF
385 .
386 . rem Save working site
387 . set / a RSENABLE_%1 =WORKENABLE
388 . set / a NEWCOUNT=0
389 . for / 1 %%I in ( 1 , 1 , %WORKCOUNT% ) do call : SAVESITE1 %1 %%I
390 . goto : EOF
391 . : SAVESITE1
392 . if not defined WORKDIR_%2_ goto : EOF
393 . set RET=%%WORKDI R_%2_%%
394 . call _mtplib : RESOLVE
395 . set / a NEWCOUNT+=1
396 . set RSDI R_%1 _%NEWCOUNT%_=%RET%
397 . goto : EOF
398 .
399 . rem / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
Chapter 7: Miscellaneous Scripts 23 1
Description
The ANIMAL.BAT script plays the classic Animal computer game, which was
originally developed during the 1 970s as a demonstration of simple artificial
intelligence. Animal is a very simple but surprisingly challenging game. The
computer maintains a database of animal species, and an additional database
of yes/no answer questions.
The game begins by the (human) player thinking of an animal. The computer
then asks a series of yes/no questions until either it correctly guesses the ani
mal, or it runs out of questions. What makes the game interesting is that the
computer then asks what animal you are thinking of, and also asks for a new
yes/no question so it can distinguish this animal from its best guess. This infor
mation is then added to the database maintained by the game. This database is
stored in a data file, and so each time the computer plays the game, it increases
its knowledge of fauna.
Eventually, it can become quite challenging to think of an animal that the com
puter cannot guess. Many years ago, one of the computers at MIT is rumored
to have amassed a database of several thousand animals, and prizes were
offered to anyone who could think of a new animal.
To play the Animal game, simply execute the script. The game has a built-in
database of only two animals: dog and duck. New animals are stored in the
data file ANIMAL.DAT, which is stored in the same directory as
ANIMAL.BAT.
232 Part II: Real-World Scripting
Implementation
The core of the ANIMAL script is a database of known animals and questions
about those animals. This database is structured as a binary tree, in which each
interior node contains a yes/no question, and each leaf contains an animal
name. Interior nodes maintain a Yes and a No branch which each point to
another (lower) node. The initial built-in tree contains one question: "Does it
have a beak ? " and two animals: "Dog" and "Duck. " The root node of the tree
contains the question. The "Yes" leaf contains "Duck" and the "No" leaf con
tains "Dog. " Leaves are distinguished from interior nodes by having no pointer
in the yes and no branches.
In the script, the tree is represented as an array of nodes. Each node is com
prised of one entry in each of three arrays:
• ANIMAL_TEXT_n_ contains the question (for interior nodes) or the name of
an animal (for leaf nodes).
• ANIMAL_YES_n_ contains the index of the node for a yes answer, or 0 if the
node is a leaf node.
• ANIMAL_No_n_ contains the index of the node for a no answer, or 0 if the
node is a leaf node.
The ANIMAL.DAT file provides persistent storage for the array, which is
stored in node index order (the actual node indices are not stored). Each line in
the file comprises a single node in the tree. The first two fields contain the yes
and no branches, and the final fields contain the node text.
To play the game, the computer simply starts at the root node, which is the
array entry at index 1 . If the node is not a leaf, it asks the question stored at
the node, and then moves down through either the Yes or No pointer (depend
ing upon the response to the question) to the next node. This continues until
the script reaches a leaf node. When this happens, the computer asks I s it
a . , where . . . is the animal name stored at the leaf.
. .
If the answer to this final question is yes, the game is over. If the answer is no,
the computer has been defeated. In this case, the computer adds new informa
tion about the new animal:
1 . The computer gets the name of the new animal.
2. The computer gets a yes/no question to distinguish its best-guess animal
from the new animal.
3. The computer then creates two new leaf nodes to contain the best-guess
animal and the new animal, and places the new question in the current
leaf.
Chapter 7: Miscellaneous Scripts 233
1 47 . set AN IMAL_TEXT_%NEWNODE_NO%_=%NODE_TEXT%
1 48 .
1 49 . echo Thank you !
1 50 . goto : EOF
151 .
1 52 . rem l ! l / ! l l l ! l l l / ! l l l l ! ! l l l ! l l ! l l / l l l ! l l ! l l ! l l ! l l l l l l l l l l l ! l l l / l ! ! l l ! l l ! I !
1 53 . rem LOADDATAFILE procedure
1 54 . rem Load an imal data f rom specified file
1 55 . rem
1 56 . rem Arguments : %1 =filename to load
1 57 . rem
1 58 . : LOADDATAFILE
159. if defined TRACE %TRACE% [ p roc %0 %* ]
1 60 . set / a ANIMALCOUNT=0
1 61 . if exist %1 (
1 62 . ( f o r / f " eol= ; tokens=1 , 2* delims= , " %%! i n ( ' type %1 ' ) do call
: LOADDATARECORD %%! %%J 1 63 . " %%K " )
1 64 . else (
1 65 . ( call : LOADDATARECORD 2 3 " Does it have a beak? " )
1 66 . ( call : LOADDATARECORD 0 0 " duck " )
1 67 . ( call : LOADDATARECORD 0 0 " d og " )
1 68 . )
1 69 . goto : EOF
1 70 .
1 71 . rem l l l / l l l l l / l l / l l l l l l l l l l l ! l l l / l l l l ! l l l l l ! l l l / l l l l l l l l ! l l ! l l ! l l l l l l l l l l l
1 72 . rem LOADDATARECORD procedure
1 73 . rem Load animal data f rom
1 74 . rem
1 75 . rem Arguments : %1 =yes answe r index ( o r 0 )
1 76 . rem %2=n o answe r index ( o r 0 )
1 77 . rem %3=question or animal n ame ( in double quote s )
1 78 . rem
1 79 . : LOADDATARECORD
1 80 . if defined TRACE %TRACE% [ proc %0 %* ]
1 81 . set T1 =%3
1 82 . set / a AN IMALCOUNT+=1
1 83 . set / a ANIMAL_YES_%AN IMALCOUNT%_=%1
1 84 . set / a ANIMAL_N0_%AN IMALCOUNT%_=%2
1 85 . set ANIMAL_TEXT_%AN IMALCOUNT%_=%T1 : " =%
1 86 . goto : EOF
1 87 .
1 88 . rem / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
1 89 . rem SAVEDATAFILE procedure
1 90 . rem Save animal data to specified file
191 . rem
1 92 . rem Arguments : %1 =filename
1 93 . rem
1 94 . : SAVEDATAFILE
1 95 . if defined TRACE %TRACE% [ proc %0 %* ]
1 96 . echo ; ANIMAL data (%ANIMALCOUNT%) >%1
1 97 . for / 1 %%! i n ( 1 , 1 , %ANIMALCOUNT%) do call : SAVEDATARECORD %1 %%!
Chapter 7 : Miscellaneous Scripts 237
1 98 . goto : EOF
1 99 .
200 . rem / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
201 . rem SAVEDATARECORD procedure
202 . rem Save specified record in file
203 . rem
204 . rem Arguments : %1 =file name to save
205 . rem %2=index into array
206 . rem
2097 . : SAVEDATARECORD
208 . if defined TRACE %TRACE% [ p roc %0 %* ]
209 . call : GETANIMALNODE %2
21 0 . echo %NODE_YES% , %NODE_NO% , %NODE_TEXT%>>%1
2 1 1 . goto : EOF
21 2 .
2 1 3 . rem / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
2 1 4 . rem GETANIMALNODE procedure
2 1 5 . rem Get a node into t h e working node
2 1 6 . rem
2 1 7 . rem Arguments : %1 =index into animal array
21 8 . rem
2 1 9 . rem Returns : NODE_ =working node loaded
• . .
220 . rem
221 . : GETANIMALNODE
222 . if defined TRACE %TRACE% [ proc %0 %* ]
223 . set / a NODE_YES=ANIMAL_YES_%1 _
224 . set / a NODE_NO=ANIMAL_N0_%1 _
225 . set RET=%%ANIMAL_TEXT_% 1 _%%
226 . call _mtplib : RESOLVE
227 . set NODE_TEXT=%RET%
228 . goto : EOF
229 .
230 . rem / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
231 . rem Additional procedures go here . . .
232 .
233 . rem These must be t h e FINAL LINES in the script . . .
234 . : DOSEXIT
235 . echo This script requires Windows NT
236 .
237 . rem / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
Scripts are not a perfect solution (by any means) to many of the everyday
problems facing managers and users of Windows NT installations. But, as this
book has tried to show, they can at least be used to manage the complexity of
these problems, by hiding complex command syntax, and automating many
repetitive and error-prone management tasks.
Happy scripting!
Command Reference
The tables in this section provide categorized lists of commands that enable
you to quickly access the complete reference information in the alphabetical
command section.
The rest of this part provides a complete alphabetical command reference for
all Windows NT shell commands. In addition, the following topics in this sec
tion provide summary information on various aspects of shell scripting:
Command Line Editing Standard Variables
Command Line Syntax Variable Syntax
Parameter Syntax
The formatting used in the syntax descriptions accompanying each command is
described in the introduction of this book. Some of the more common syntax
elements used in commands are shown in the following table.
Syntax Description
.ext A file extension, typically of 1 to 3 letters, prefixed
with a period.
args An arbitrary list of command arguments, typically
separated by spaces.
command Any valid Windows NT scripting command, possi
bly including arguments.
command- name Any valid Windows NT script command name,
without arguments.
computer A NetBIOS computer name, typically prefixed
with \ \ .
drive: A drive letter followed by a colon character.
file A combination of a drive letter, path and file name.
filename A file name only, without a drive or directory path.
This can be a long file name, possibly including
spaces, unless noted otherwise.
filetype A registry defined file type name.
label A script label.
248 Part III: Scripting Command Reference
nn A decimal number.
path A directory path. One or more directory names
separated by backslash characters. Paths that begin
with a backslash are absolute paths that start at
the root directory. Paths that begin with a directory
name are relative to the current directory.
swi tches If a command has a large number of optional
switches, these are all represented by swi tches in
the command syntax.
uncname A UNC name, such as \\server\share\path.
var An environment variable name.
Reserved shell character Any of the special characters &, : , (, ) or A .
Where a command has several syntax variations, these are numbered in the
syntax description. The text then refers to a specific variation by this number.
For example, ASSOC ( 2 ) refers to syntax variant 2 of the ASSOC command.
Command examples follow the conventions used throughout this book.
Commands are shown in lowercase except for variable names and script labels,
which are shown in uppercase.
ADDUSERS [ RK ]
Creates, updates and deletes user accounts.
Syntax:
1. ACCUSERS [ \ \ computer ] ID [ dri ve : ] [path ] fil ename [ I S : c ]
2 . ACCUSERS [ \ \ computer ] I C [ dri ve : ] [path ] fil ename [ I S : c ]
3 . ACCUSERS [ \ \ computer] I E [ dri ve : ] [path ] fil ename [ I S : c ]
Switches:
ID Dumps user accounts to fil ename .
IC Creates accounts as specified by the contents of filename.
IE Deletes accounts a s specified by the contents of filename.
IS:c Sets the field delimiter character to c.
The ADDUSERS command creates, updates, or deletes user accounts on the speci
fied computer. The local account database is used if no computer is specified.
Account information is accessed via a text file, allowing large numbers of
accounts to be rapidly processed.
The account file used by ADDUSERS is a text file containing comma-delimited
records suitable for processing with a spreadsheet program. If required, the IS
switch changes the delimiter character used in the file.
Alphabetical Listing of Commands 249
Use ADDUSERS ( 1 ) to dump the account database of the specified computer (or, by
default, the local computer) to the specified fil ename. This records account
information for later restore, if needed. It also creates a prototype account file
to assist in the preparation of a new file for ADDUSERS ( 2 ) and ADDUSERS ( 3 ) . All
information about accounts, local groups and global groups is saved except
account password information.
Use ADDUSERS ( 2 ) to create accounts, local groups and global groups.
Information for the accounts to create is taken from the specified account file.
Passwords for newly created accounts are left blank.
Use ADDUSERS ( 3 ) to delete accounts, local groups and global groups.
Information for the accounts to delete is taken from the specified account file.
Take care when deleting accounts-the Windows NT security model does not
allow an account to be recreated once deleted.
The account file is a text file that is divided into three sections: for user
accounts, local groups and global groups. Each section begins with a header,
which is [ User ] for the user account section, [ Global ] for global groups, and
[ Local ] for local groups. Not all sections need be present in the account file.
Following the appropriate header are individual records for each user, global
group, or local group, one record per line. For user accounts, the record is
organized as follows:
User Name, Full Name, Password, Home Drive, Home Path, Profile, Script
For global groups, the record is organized as follows.
Global Group Name, Comment, UserName, ...
For local groups, the record is organized as follows.
Local Group Name, Comment, UserName, ...
For both global and local groups, the UserName element is repeated as often
as needed for each user in the group.
ASSOC
Displays and alters file associations.
Syntax:
1. ASSOC
2. ASSOC . ext
3. ASSOC ext=
•
The ASSOC command displays and alters the mapping between file extensions
and file types. A file type is a named registry entry describing a type of file and
250 Part ID: Scripting Command Reference
how to launch its associated application. Use ASSOC to connect a file type to one
or more file extensions (and hence to an application). File types are manipulat
ed by the FTYPE command.
Use ASSOC ( 1 ) to display all current associations, and ASSOC ( 2 ) to display a spe
cific association. Use ASSOC ( 3 ) to delete an existing association, and ASSOC ( 4 ) to
create a new association or change an existing one.
After you create an association, you can automatically invoke an application
by opening a file with the associated extension. You can also use the PATHEXT
standard variable to further automate the association.
Example:
ftype NotePad=notepad . exe " %1 "
assoc . abc=NotePad
set PATHEXT=%PATHEXT% ; . abc
These commands first create a new file type called NotePad, which will execute
NOTEPAD.EXE. Then the file extension .ABC is associated with this type.
Finally, the .ABC extension is added to the path extension list. Once these com
mands are executed, entering DATA at the command prompt opens the file
DATA.ABC in Notepad.
Notes:
File type information and file extension associations are stored in the
HKEY_CLASSES_ROOT section of the registry. Therefore, changes made
using the ASSOC command are retained across system shutdowns and will affect
all users.
See also: ASSOCIATE, FTYPE, Standard Variables, START
ASSOC IATE [ R K ]
Creates or deletes file associations.
1 . ASSOCIATE . ext
2 . ASSOCIATE . ext ID [ / F l
3 . ASSOCIATE . ext [ dri ve : l [path l filename [ / F l
Switches:
ID Deletes association.
/F Forces operation without a confirmation.
The ASSOCIATE command displays and alters the associations between file exten
sions and an application. ASSOCIATE combines the ASSOC and FTYPE commands
into a single step process.
Alphabetical Listing of Commands 251
AT , WI NAT [ R K ]
Schedules commands to execute at a specified time and date.
Syntax:
1. AT [ \ \ computer)
2. AT [ \ \ computer ) / DELETE ( / YES )
3. AT [ \ \computer) id / DELETE
4. AT ( \ \ computer) time [ / INTERACTIVE ) ' command "
5. AT ( \ \ computer) time ( / INTERACTIVE ) / NEXT : date [ , . . . ) " command "
6. AT ( \ \ computer] time [ / INTERACTIVE ) / EVERY : date [ , . . . ] " command "
Switches:
/ DE LETE Deletes either the specified command or all
commands.
/ YES Deletes all commands without prompting for con
firmation.
/ I NTERACT IVE Allows the scheduled command to interact with the
desktop.
/ N EXT Specifies that the command executes once on the
specified date.
/ EVERY Specifies that the command executes repeatedly on
the specified date.
252 Part III: Scripting Command Reference
Notes:
The AT command relies upon the Windows NT Schedule service to execute
scheduled commands. If necessary, start this service using Windows NT
Control Panel or the WI NAT [ RK J command. The service must execute in an
account with sufficient rights to access the resource needed by the command,
such as shared directories.
Alphabetical Listing of Commands 253
ATTR I B
Displays or changes the attributes of one or more files.
Syntax:
1 . ATTRIB [ /SJ
2. ATTRIB [ drive : J [path J filename [ /SJ
3. ATTRIB [ +R : · R ] [ +A : ·AJ ( +S : · SJ [ +H · H J [ dri ve : ] [path ] filename [ /SJ
Switches:
+R ·A Sets o r resets the read-only attribute.
+A ·A Sets or resets the archive attribute.
+S -S Sets or resets the system attribute.
+H -H Sets or resets the hidden attribute.
IS Searches for matching files in all sub-directories.
The ATT R I B command sets or resets the attributes of specified files. Attributes
include R for read-only files, A for archived files, s for system files, and H for
hidden files. Use the " + " form to set the attribute, and the " -" form to reset it.
Use ATTR I B ( 1 ) to display the attributes of all files in the current directory. The
/S switch displays attributes of files in the current directory and all sub-directo
ries. Use ATTR I B ( 2 ) to display the attributes for a single file or a set of files
matching a wildcard file name. Use ATTR I B ( 3 ) to alter attributes of the specified
file or files. You can specify multiple attributes to alter by placing a space
between each attribute.
Use the fil ename argument to specify the files to alter or display. Wildcards can
be used. If no file name is specified, * . * is assumed. Note that ATTR I B requires a
space between the end of the file name and the I s switch, if present.
Example:
attrib +r +s +h c : \ boot . in i
See also: D I R, D E L .
254 Part III: Scripting Command Reference
AUD I TPOL [ R K ]
Displays or alters Windows NT auditing policies.
Syntax:
1 . AUDITPOL [ \ \ compute r ]
2 . AUDITPOL [ \ \ computer] [ / ENABLE / DISABL E ) [ / cat : opt ) [ . . . ]
Switches:
/ ENABLE Enables auditing (default).
/ DISABLE Disables auditing.
l cat : opt Sets auditing options for audit category cat to opt.
The AUDITPOL command displays or alters Windows NT auditing policies. By
default, the AUDITPOL command processes policies on the local computer.
Specify computer to process policies on remote computers
Use AUDITPOL ( 1 ) to display current policies for the specified computer or the
local computer. Use AUDITPOL ( 2 ) to alter auditing policies. The / ENABLE or
/ DI SABLE switches enable or disable auditing. Each category switch ( l cat : opt )
sets specific policies for the computer.
The categories used for cat are as follows:
• System Audit system events.
• Logan Audit logon/logoff events.
• Object Audit object access.
• Privilege Audit use of privileges.
• Process Audit process creation and termination.
• Policy Audit security policy changes.
• Sam Audit SAM changes.
Each category is followed by an opt option to control the auditing for that cat
egory. The options used for opt are as follows:
• Success Audit success events.
• Failure Audit failure events.
• All Audit all events in this category.
• None Do not audit this category.
Example:
auditpol \ \ t ransfe r - 4 / enable / logon : failure
Alphabetical Listing of Commands 255
AUTOEXEC . BAT
The MS-DOS startup script.
Windows NT does not process AUTOEXEC.BAT in the same way as MS-DOS.
The script file is not processed at system startup. Instead, Windows NT scans
C:\AUTOEXEC.BAT during logon. During scanning, any SET and PATH com
mands are processed, thus adding to or modifying the user environment vari
ables. Environment variables set through AUTOEXEC.BAT are set after those
defined for the system and the user through Control Panel. These variables are
then available to all applications, including Windows NT command shell
sessions.
Windows NT only scans AUTOEXEC.BAT; it does not execute it. If the script
contains conditional statements ( I F, GOTO, etc.) that are used to control the set
ting of environment variables, the results can be unpredictable.
The PATH variable is treated specially. Any PATH commands or SET PATH com
mands in AUTOEXEC.BAT append the path value to the current path, rather
than over-writing it.
You can disable the processing of AUTOEXEC.BAT at logon using the follow
ing registry value:
HKEY_CURRENT_USER\Software\Microsoft\
Windows NT\CurrentVersion\Winlogon\ParseAutoexec
Set this value to a type of DWORD and a value of 1 to enable parsing, or 0 to
disable parsing. Note that this value is per-user, not per-system.
Notes:
The Windows NT Resource Kit ships with a tool, AUTOEXNT, which enables
Windows NT to execute an equivalent to AUTOEXEC.BAT at startup.
CACLS , XCAC LS [ R K ]
Displays and modifies access control lists of files.
Syntax:
1. CACLS [ dri ve : ] [path ] filename [ / T l
2. XCACLS [ dri ve : ] [path ] filename [ / T ]
3. CACLS [ dri ve : ] [ path ] fil ename [ swi tches ]
4. XCACLS [ dri ve : ] [path ] filename [ swi tches ]
Switches:
IT Processes files in the current directory and all sub
directories.
/E Edits ACLs instead of replacing them.
256 Part III: Scripting Command Reference
When directory permissions are displayed, the output consists of two lines for
each user or group granted access to the directory. The first line shows file per
missions, while the second shows directory permissions. Each permission type
is identified by a two letter code as follows:
Permission Code Permission Type Description
(OI) Object Inherit Specifies the permissions that are
inherited by files copied into or cre
ated in this directory.
(IO) Inherit Only Specifies that the 01 or CI permis
sions apply only to created or
copied files, and not to the directo
ry itself.
(Cl) Container Inherit Specifies the permissions that are
inherited by directories copied into
or created in this directory.
(NP) No Propagation Specifies that the listed permissions
are not be to propagated into new
ACLs.
Alphabetical Listing of Commands 257
Use CACLS ( 3 ) or XCACLS ( 4 ) to modify or replace the permissions for the files and
directories specified. These commands edit or replace the access control lists
(ACLs) that are used to control access rights to files and directories. By default,
CACLs/XCACLS replaces the entire ACL with a new one based on the supplied
switches. Use the / E switch to edit the existing ACL instead (that is, the exist
ing ACL is altered by the CACLslXCACLS command, rather then being replaced by
a new one).
The / R switch removes all ACL entries (ACEs) for the specified user from the
ACL, thus revoking all rights for that user. This makes sense only when editing
the ACL (with the / E switch), since replacing the ACL will revoke all existing
permissions anyway. Multiple user names can be specified following the / R
switch.
The / D switch adds an access denied ACE to the ACL for the specified user.
This denies all access for the specified user. Multiple user names can be speci
fied following the I o switch.
The /G switch specifies an access allowed ACE for the specified user. Specify
permissions granted to the user using perm. The following table shows valid
characters that can be part of perm.
Valid Character Description
R Read access.
c Change (write) access.
F Full control.
p Change permissions (special access) .
0 Take ownership (special access).
x Execute (special access) .
E Read (special access).
w Write ( special access).
D Delete (special access) .
The R (read), c (change, that is, write) and F (full control) permissions are nor
mal permissions, which are actually combinations of the other (special access)
permissions. These are the only permissions accepted by CACLS; the other per
missions are recognized by XCACLS only.
The / P switch is similar to / G, except that the specified permissions replace any
that already exist when editing an ACL.
When applied to a directory, the XCACLS command can manipulate the directory
permissions and file inheritance permissions separately. Specify directory per
missions in perm and file inheritance permissions in sp.
258 Part ill: Scripting Command Reference
Notes:
Group names can be substituted for user names anywhere in a CACLS/XCACLS
command. These should be quoted if they contain spaces.
When evaluating permissions, Windows NT will stop processing an ACL when
access has been explicitly denied or granted. Therefore, always place access
denied ACEs before access granted ACEs in an ACL (that is, place all t o
switches before /G and / P switches) .
CAL L
Invokes another script file or script label as a procedure.
Syntax:
1 . CALL [ dri ve : ] [path ] filename [ args ]
2 . CALL : label [ args ]
The CALL command invokes another script as a procedure. The invoked script is
executed and, upon completion, execution of the current script continues at the
statement following the CAL L statement.
Use CALL ( 1 ) to call a script in another file (either .BAT or .CMD ) . Execution
begins at the first line in the file. Use CALL ( 2 ) to call a script procedure within
the current script file, at the location specified by l abel . Execution begins at
the first line following the specified label. You must always precede l abel with
a colon.
Execution of the procedure ends when the end of the script file is reached. You
can quickly jump to the end of the script file using GOTO : EOF, which therefore
acts as a "return" statement for the procedure.
Arguments to the procedure are handled in a similar manner to those passed to
a script from a command line, including special parameter substitutions.
The environment is shared between the caller and the callee. Thus the callee
can access variables set by the caller, and can use a variable to return a result
from the procedure upon completion. A common convention is to use the RET
variable for this purpose.
Example:
echo Step 1
call : SUB1
echo step 3
goto : EOF
: SUB1
echo Step 2
goto : EOF
Alphabetical Listing of Commands 259
CD
See CHOIR.
CHO I R, CD
Changes or displays the current directory.
Syntax
1 . CHOIR [ drive : ]
2. CHOIR path
3 . CHOIR [ /D J drive : path
4 . CHOIR • .
5 . CD [ drive : ]
6 . CD path
7 . CD [ / D J drive :path
8 . CD . .
Switches:
/D Changes the current drive in addition to changing the current
directory.
The CHOIR command displays or alters the current directory for a specified
drive. The co command is a synonym for CHOIR.
Use CHOI R { 1 ) or co { 5) to display the current directory for a drive. If no drive is
specified, the current directory for the current drive is displayed.
Use CHDI R { 2 ) or CD { 6 ) to change the current directory on the current drive. The
specified path can be absolute (starting at the root of the drive) or relative to
the current directory. Use CHDI R ( 3 ) and CD ( 7 ) to change the current directory on
a specified drive. If the /D switch is specified, the current drive changes to
dri ve .
Use CHDI R { 4 ) or CD ( B ) to move one level up the directory tree (towards the root
directory) on the current drive. This command is not valid at the root of a
directory tree.
The CHOI R command changes the case of the specified path to match that actu
ally found in the directory tree. If the command shell prompt includes the cur
rent path name, this is reflected in the displayed path name.
260 Part III: Scripting Command Reference
Unlike most other shell commands, the CHOIR command accepts path names
containing spaces without the need to use double quotes, although these can
still be used if desired. Also, CHOIR allows wildcards as path names, and
changes to the first directory found whose name matches the wildcard speci
fied. This is convenient with long directory names, as it is only necessary to
type enough of the path name to uniquely identify the directory, and then add
a trailing " * " to the path name.
Command completion editing is particularly useful with the CHOIR command, as
only the first few characters of the directory path need to be typed, followed
by the command completion key.
Notes:
Current directories are maintained independently for each drive and command
shell. New command shells inherit the current drive and directories of the
invoking command shell.
See also: MKOIR, RMOIR, Command Line Editing
CHO I C E [ R K ]
Obtains keyboard input for script.
Syntax:
1 . CHOICE ( / C : choices ] ( / N J [ /SJ [ /T : c , nn] [prompt]
Switches:
IC Specifies allowed choices.
/N Do not display choices and prompt character.
IS Treat choices as case sensitive.
IT Default choice after a specified timeout.
The CHOICE command waits for the user to type a keystroke and then returns
this keystroke as an exit code. The keystrokes allowed are specified by choices.
The default choices are YN. Normally, choices are not case sensitive. Use the /S
switch to make choices case sensitive.
Use CHOICE ( 1 ) to display the prompt text followed by a list of valid choices in
brackets and a question mark. The / N switch suppresses the display of the
choice list and question mark, in which case only prompt is displayed.
By default, the CHOICE command waits forever for user input. The /T switch
specifies a default choice c and a timeout period of nn seconds. If there is no
user input within nn seconds after displaying the choice, CHOICE automatically
returns choice c.
Alphabetical Listing of Commands 261
The CHOICE command returns the selected choice as an exit code value. The
choice is returned as an index into the choices choice list, with the first choice
corresponding to 1 . Thus the default YN choice list returns an exit code of 1 for
v and 2 for N. The exit code value is available via the IF ERRORLEVEL command
and % ERRORLEVEL% variable.
Example:
cmd / c choice / c : SPX Enter netwo r k card type
if errorlevel 3 goto card_X
if errorlevel 2 goto card_P
if er rorlevel 1 goto card_S
echo invalid choice
goto exit
Notes:
The IF ERRORLEVEL command is true if the exit code is greater than or equal to
the specified value. Therefore test choice values in descending order to ensure
correct operation.
Some versions of the CHOICE command, including the version shipped with the
Windows NT Resource Kit, contain a bug. After the CHOICE command executes,
console input is suppressed for future interactive commands within a script. To
avoid this problem, execute the CHOICE command within a nested command
shell.
CL I P [ RK]
Captures command input to the Clipboard.
Syntax:
1 . CLIP < [ dri ve : ] [path ] filename
2 . command : CLIP
The CLIP command captures its command input and places it as text in the
Windows NT Clipboard. It is then available for pasting into any Windows
application.
Use CLI P ( 1 ) to place the contents of the specified file into the Clipboard. Use
CLI P ( 2 ) to capture the command output from command and place it in the
Clipboard.
Example:
dir clip
C LS
Clears the console window.
262 Part ill: Scripting Command Reference
Syntax:
1 . CLS
The CLS command clears the console window and positions the cursor to the
top left location in the window. The window is cleared to the colors specified
for this window. These are selected either via the console window menu or via
the COLOR command.
If you use large console windows (larger than the default 80 columns by 25
rows), then the CLS command is useful before executing legacy applications that
only execute in 80 column by 25 row mode. Using CLS first ensures that the
unused portions of the console window are cleared of distracting characters.
See also: COLOR
CMD
Executes the default Windows NT command shell.
Syntax:
1 . CMD [ / X : /Y I [ /A : / U ] [ / Q) [ /T : bf]
2. CMD [ / X : /Y I [ /A : / U ] [ / Q) [ / T : b f] / C command
3 . CMD [ / X : /V J [ /A : / U ] [ / Q) [ / T : bf] / K command
Switches:
IX Enable command extensions (default).
/Y Disable command extensions.
/A All command output to files or pipes will be ANSI (default) .
/U All command output to files or pipes will be Unicode.
/Q Turn echo o ff by default when executing scripts (non-
functional) .
IT Sets foreground and background window colors.
/C Execute command specified and then terminate shell.
/K Execute command specified and then prompt for additional
commands.
The CMD command invokes a Windows NT command shell. Use CMD ( 1 ) to
invoke a normal shell, which then prompts for commands to execute. Use
CMD ( 2 ) to execute command. After execution completes the shell terminates. Use
CMD ( 3 ) to execute command. After execution completes the shell remains in mem
ory and prompts for additional commands.
Alphabetical Listing of Commands 263
The /A and /U switches control the format of command output sent to a pipe
or file by this command session. If /A is used (the default), output will be 8-bit
ANSI characters. If /U is used, output will be 1 6-bit Unicode characters.
The /T switch changes the foreground and background colors used by the con
sole window. See the COLORS command for the meaning of the bf argument. If
I T is not specified, the command shell uses the current console window colors,
or the colors specified in the shortcut used to start the console window. If none
of these are specified, the colors set in the Control Panel Console settings are
used.
Notes:
The / Q switch (not listed in the preceding text) is documented as disabling com
mand script echo. However, it appears to be non-functional in all versions of
the command shell tested.
The / E switch is also not functional, although for backward compatibility,
CMD.EXE accepts it. Microsoft Knowledge Base article Q158141 states that
this switch alters the size of the environment available under Windows NT.
This information is incorrect. Windows NT does not set a fixed upper limit on
the size of the environment used by 32-bit applications, including CMD.EXE.
Example:
cmd / x /c " mysc ript . bat '
COLOR
Sets the console window foreground and background colors.
Syntax:
1 . COLOR
2 . COLOR bf
The COLOR command changes the foreground and background colors of the cur
rent console window. Use COLOR ( 1 ) to restore the console window colors to
those in effect when the command shell was started.
Use COLOR ( 2 ) to set the colors to bf. This is a two character parameter, the first
character of which specifies the background color, the second the foreground
color. The colors are taken from the following table.
0 Black 8 Gray
1 Blue 9 Light Blue
2 Green A Light Green
3 Aqua B Light Aqua
4 Red c Light Red
5 Purple D Light Purple
6 Yellow E Light Yellow
7 White F Bright White
Example:
color 1 7
COMMAND
Executes the MS-DOS command shell.
Alphabetical Listing of Commands 265
Syntax:
1 . COMMAND [ / E : nn )
2 . COMMAND [ / E : nn ] / C command
Switches:
/E Specifies the number of bytes to reserve for environment vari
able storage.
/C Execute command specified and then terminate.
The COMMAND command invokes an MS-DOS command shell. Windows NT pro
vides a 16-bit MS-DOS compatible command shell, COMMAND.COM. This
shell can be used to execute older MS-DOS scripts that do not execute correct
ly on the default Windows NT shell, CMD.EXE.
Use COMMAND ( 1 ) to invoke an MS-DOS shell, which prompts for commands to
execute. Use COMMAND ( 2 ) to execute command. After execution completes, the shell
terminates.
The I E switch can be used to specify the size, in bytes, of environment variable
storage in the shell.
While an MS-DOS command shell is executing, clicking the close box of the
console window will not close the console window. Exit the MS-DOS com
mand shell using the EX I T command first.
The MS-DOS shell does not support the same command line editing as the
Windows NT shell (CMD.EXE). However, once a command is submitted for
execution (by pressing Enter), the complete command line is passed to a
Windows NT shell for execution. Thus the MS-DOS command shell inherits
many of the features of the Windows NT shell, including most command line
syntax and the ability to execute 16 and 32-bit windows applications.
Notes:
Other switches documented elsewhere for COMMAND.COM are not valid
under Windows NT and may cause unpredictable behavior.
If you include the current path in your command prompt, the MS-DOS shell
displays this using short names, that is, uppercase " 8 . 3 " names, not mixed case
long file names.
See also: CMD, EXIT, Command Line Syntax.
266 Part III: Scripting Command Reference
Template editing keys use the command template. The command template is a
hidden copy of the most recent command entered. The template editing keys
are shown in the following table.
Key Description
Fl Copy the template character at the same column position as the
cursor into the command.
F2 Search and insert template characters. Press F2 and then a char
acter in the template. Characters are copied from the template up
to, but not including, the first character matched in the template.
F3 Copy all remaining template characters starting from the current
cursor position.
F4 Delete characters. Press F4 and then a character. Characters in
the command line are deleted starting from the cursor up to, but
not including, the first character matched in the command.
FS Copy the entire template into the command.
Command history editing keys access a list of recently typed commands. These
can be recalled for editing and re-execution. The history editing keys are
shown in the following table.
Alphabetical Listing of Commands 267
Keystroke Description
Up arrow Recall commands from the newest to the oldest.
Down arrow Recall commands from the oldest to the newest.
Page Up Recall the oldest command.
Page Down Recall the newest command.
F7 Displays the command history list in a popup window.
Use the cursor keys to move up and down the list. Press
Esc to close the window, or Enter to execute the selected
command. Commands in the list are numbered for use by
F9. The command history popup does not appear if the
history list is empty.
Alt+F7 Clears the command history of all commands.
F8 Recalls commands that match the characters typed at the
command line. A command matches if the command
starts with the same characters typed at the command
line. Repeatedly pressing F8 cycles through all commands
in the history buffer that start with the typed characters.
F9 Recalls a command from the history by command num
ber. After recall the command can be edited before execu
tion. Command numbers are displayed by pressing F7.
HKEY_CURRENT_USER\Software\Microsoft\Command
Processor\CompletionChar
Once command completion editing is enabled, type the first few letters of a file
or directory name, and then press the command completion key (such as the
Tab key). The partial file name will be completed using the first matching file
name in the current directory. Press the command completion key again to
cycle through all matching files or directories in the current directory.
Notes:
Command-Line Syntax
Special symbols used in commands.
The Windows NT shell processes certain symbols that are entered as part of a
command. These symbols are not visible to the command itself (that is, they are
stripped from the command text by the shell before the command is executed).
The command redirection symbols control command input, command output
and command error output. The symbols are shown in the following table.
Command Description
>file Redirects command output to the file specified. You can
also use a standard device name such as LPTl, CON,
PRN or CONOUT$ as the file name. Any preexisting con
tents of the file are lost.
»file Redirects command output to the fil e specified. If the file
already exists, all command output is appended to the end
of the file.
<file Redirects command input from the fil e specified. You
can also use a standard device name such as CON or
CO NIN$.
2>file Redirects command error output to the fil e specified.
You can also use a standard device name such as LPTl ,
CON, PRN or CONOUT$ as the file name. Any preexist
ing contents of the file are lost.
2>&1 Redirects command error output to the same location as
command output. This makes any command output redi
rection also apply to command error output.
cmd1 cmd2 Pipes the command output of cmd1 to the command input
of cmd2. Multiple pipe characters are allowed, creating a
chain of commands, each sending output to the next com
mand in the chain.
Command Description
cmd1 & cmd2 Executes command cmd 1 , then command cmd2. Additional
commands can be added using additional ampersand
symbols.
cmd 1 && cmd2 Executes command cmd 1 , then executes command cmd2
only if cmd1 completed successfully.
cmd1 : : cmd2 Executes command cmd 1 , then executes command cmd2
only if cmdl did not complete successfully.
( ) Use parentheses to indicate the nesting of complex multi
command sequences. Also used in IF . . . ELSE commands
and multi-line commands.
When executing commands using the conditional symbols && and : : , the sec
ond command only executes if the previous command either did, or did not,
complete successfully. A "successful" command is one that returns an exit code
of 0. An unsuccessful command is one that returns an exit code of non-zero.
Exit codes can be accessed via the %ERRORLEVEL% variable or the IF ERRORLEVEL
command.
To over-ride the meanings of special symbols and treat them as regular charac
ters, precede the symbol by a carat Acharacter. To enter a literal carat character,
use two carat characters in sequence.
Example:
dir * . txt >>list . txt
dir * . exe ts : more
(dir c: & dir d : ) : more
This last example shows the use of parentheses. With the parentheses, the out
put of both D I R commands is sent through a pipe to the MORE command, one
after the other. Without the parentheses, only the output of the second com
mand is sent to the pipe.
Notes:
Variable substitution and parameter substitution occur before the shell processes
special symbols. Therefore, it is possible to place special symbols within vari
ables or parameters and have them processed by the shell as part of a command.
See also: Variable Syntax, Parameter Syntax, Command Line Editing
COPY
Copies files.
Syntax:
( 1 ) COPY [ IA : / B J source [ /A / B J [ + . . . ] [ destination [ /A : / B J ] [ /V J [ / N J [ / Z J
2 70 Part III: Scripting Command Reference
Switches:
IA Copy files i n ASCII mode.
/B Copy files in binary mode.
/V Verify file copy operations.
/N Use short (MS-DOS) file names aduring copy.
/Z Use restartable copy mode.
The COPY command copies files from one location to another, or to a device
(such as LPT1 or CON) . COPY copies files either in binary mode or ASCII
mode. In binary mode, COPY performs a byte-by-byte exact copy of the file spec
ified. In ASCII mode, COPY performs a byte copy up to, but not including, the
first end-of-file character ( Ctrl+Z) encountered in the source. If the destination
is specified as ASCII, then a single end-of-file character is appended to the end
of the file.
The /A switch selects ASCII mode and the /B switch selects binary mode. The
default mode is binary, unless the COPY command is combining files. Multiple /A
and /B switches can be specified in the COPY command. Place a /A or /B switch
before the first source file to set the default COPY mode. Subsequent switches
placed after a file name change the copy mode for that file and also for addi
tional files specified in the COPY command, until another /A or / B switch is
encountered.
The /V switch forces the COPY command to verify all file copy operations. The
/ N switch uses short (MS-DOS) file names instead of long file names. The / Z
switch copies all files in restartable mode. In restartable mode, the COPY com
mand tracks the file copy progress in the destination file so that the copy oper
ation can be restarted. This is used primarily when copying files across WAN
network connections.
The source can be a single file, a wildcard file name, a path, or a device. The
source can also be a list of files, separated by +characters. The des tination can
be a single file, a path, or a device. If des tination is not present, the current
drive and directory is assumed as the destination for the copy.
The COPY command can be used to combine files by concatenating several files
into one output file. Files are combined if the s ource specifies multiple files
separated by +characters, or if a destination file is specified and the source is
specified using a wildcard. The default mode when combining files is ASCII.
Example:
copy c : \ bin e : \temp\bin
copy c : \ • . txt lpt 1 :
copy a . cpp+b . cpp+c . cpp sys1 . cpp
Alphabetical Listing of Commands 271
Notes:
Use the XCOPY command to copy complete directory trees.
See also: XCOPY, ROBOCOPY, SCOPY, MOVE, REPLACE
DATE
Displays or sets the system date.
Syntax:
1 . DATE
2 . DATE date
3 . DATE / T
Switches:
IT Do not prompt for a new date.
The DATE command displays or sets the system date. Use DATE ( 1 ) to display the
current date and display a prompt asking for the new date. Press Enter only to
leave the date unchanged. Use DATE ( 2 ) to set a new date directly from the com
mand line. Use DATE ( 3 ) to display the date only.
Dates should be entered in the form mm-dd-yy.
DE L, E RASE
Deletes files.
Syntax:
1 . DEL [ I P ] [ I F ] [ IS ] [ IQ ] [ /A : attr] [ dri ve : ] [path ] filename
2 . ERASE [ / P l ( / F l [ / S J ( / Q ] ( /A : attr] [ dri ve : ] [path ] filename
Switches:
/P Prompt for confirmation before deleting each file.
/F Force delete of read-only files.
IS Search specified directory and all sub-directories for files
to delete.
/Q Quiet mode. Skip global wildcard confirmation prompt.
/ A : a t tr Select files to delete based on attributes.
The DEL command deletes files from directories. It does not delete directories.
The ERASE command is a synonym for DEL .
272 Part III: Scripting Command Reference
The filename specifies the name of the file to delete. Wildcards are allowed. If
the fil ename is * . *, the DEL command prompts for confirmation before deleting
all files in the directory. This prompt can be defeated by using the 1 a switch.
The I P switch prompts for confirmation of each individual file deletion. The I F
switch forces DEL to delete read-only files. Normally these files are not deleted.
The IS switch deletes files in the current directory and all subdirectories that
match the fil ename. If the path is specified, files in the specified directory and
all its subdirectories are deleted. (Subdirectories themselves are not deleted,
only the files they contain.)
The I A switch selects files by attributes, in addition to name. The a ttr argu
ment can include any of the following items:
Character Description
R Select read-only files
S Select system files.
H Select hidden files.
A Select files needing archiving.
Prefix an attribute letter to invert the selection.
Example:
del l a : - a Is c : \workdir
This example deletes all files in the C: \WORKD I R tree which do not require
archiving (that is, have already been placed in a backup set).
See also: RMD I R
DIR
Lists files in a directory.
Syntax:
1 . DIR [ drive : J [path ) [ filename ] [ switches )
Switches:
IP Pause after each page of information.
IW Wide format.
ID Wide format sorted by column.
IB Bare format, without summary information.
IN Long list format (default).
IA [ : J attr Filter files to display by specified attributes.
I O [ : ] sort Specify sort order for files.
Alphabetical Listing o f Commands 273
The I N switch formats the D I R output using the long file name format, with
names in the right-most column. This is the default output format. To output
in a format compatible with MS-DOS, use the 1 - N switch. The IW switch dis
plays DIR output in wide format, with multiple names per line. Directory
names are enclosed in brackets. The I D switch is similar to IW, except that
names are sorted in columns, rather than in rows. Finally, the I B switch forces
"bare" output. This format outputs one name per line and suppresses all addi
tional information output. Bare format is suitable for input into other com
mands for additional processing.
The I A switch filters files by attributes, as specified by attr. The following table
shows valid attr characters.
Character Description
D Filter for directories only.
R Read-only files and directories only.
H Hidden files and directories only.
s System files and directories only.
A Archivable file and directories only.
Invert meaning of filter.
The ;o switch sorts files for display. The default is unsorted (although
Windows NT NTFS directories are naturally sorted by file name). The follow
ing table shows valid sort characters.
Character Description
N Sort alphabetically by name.
E Sort alphabetically by file extension.
G Group directories before files.
s Sort by file size (smallest first). Directories always have a
size of 0.
D Sort by date and time (oldest first).
Invert the sort order.
The / T switch selects the time field for display and/or sorting (if / O : D is also
specified) . Use / T : C to sort/display by the files creation time. Use / T : A to
sort/display by the files last access time. Use / T : W (the default) to sort/display
by the files last modification time. File create and access times are only avail
able in NTFS partitions.
The /L switch forces file names to be displayed using all lowercase. The / X
switch adds an additional display column to the / N format, showing the MS
DOS compatible (short) file name in addition to the full (long) file name. The
IC switch displays thousands separators (commas in North America) in all
numeric fields. To disable this, use / - C.
Example:
dir c : \winnt \ syst em32 \ * . exe / O : D / B : FIND / I " ras "
D I RUSE [ R K ]
Displays directory and file space usage statistics.
Syntax
1 . DI RUSE [ I S /VJ [ /M / K : / B ] [ / C ) [ ! , ) [ / * ) dirs
2 . DI RUSE [ / S /V) [ /M / K : / B ) [ / C ) [ / , ] [ / * ) / Q : nn [ / L I [ /A) [ / D I [ /0 )
di rs
Switches:
IS Include subdirectories in the output.
/V Display progress while scanning subdirectories.
Alphabetical Listing of Commands 275
The DI RUSE command computes directory and file size statistics. The totals
reported by DIRUSE are computed by adding up the exact file sizes, rather
than the space occupied on disk by the files. Therefore, the numbers reported
by DI RUSE may be lower than the actual amount of disk space used.
Use DI RUSE ( 1 ) to report file sizes only. Use DI RUSE ( 2 ) to report file sizes and
check for directories that exceed a specified threshold size.
Without any switches, D I RUSE reports the total bytes used by all files in each of
the directories specified by dirs . Several directories can be specified. For each
directory, D I RUSE computes the size of all the files in the directory and all subdi
rectories. The JS switch displays file size totals for each individual subdirectory
in each specified directory. Alternatively, the /V switch shows scan progress
during total computations.
The IM, /K and /B switches set the scale value used. The /B switch displays
results in bytes. The / K switch displays results in kilobytes ( 1 kilobyte = 1 024
bytes) . The /M switch displays results in megabytes ( 1 megabyte = 1 ,048,576
bytes) . These switches also control the interpretation of the nn value specified
in the / Q switch as bytes, kilobytes, or megabytes.
If NTFS compression is used, D I RUSE uses the expanded file size when comput
ing totals. The JC switch uses the compressed file size instead.
The / * switch computes totals for each top-level directory within each of the
specified dirs. This allows a quick break down of a disk drive into usage by
directory, by specifying the root of the drive.
276 Part III: Scripting Command Reference
The /Q switch sets a threshold level for directory checking. The nn value is
interpreted according to the / M, / K and /B switches. Any directory whose size
exceeds the threshold is marked with a " ! " in the output. The ID switch to
restricts output only to directories whose size exceeds the threshold. The I A
switch generates an administrative alert if the threshold is exceeded. The /0
switch prevents subdirectories from being checked for overflow-only the
directories specified by di rs are checked.
Example:
diruse c : \ /* /k / ,
Displays the disk space used, in kilobytes with comma separators, by each
directory off the root of drive C:.
See also: DIR, DISKUSE
D I SKUSE [ R K ]
Displays file usage statistics by user.
Syntax:
1 . DI SKUSE dir [ swi tches ]
Switches:
/ F : file Store command output in the specified file.
/ E : file Store command error output in the specified fil e.
/ U : user Compute usage for the specified user only.
/S Include subdirectories in the scan.
/T Use table format for output (space or comma delimited).
/W Unicode output (default is ASCII).
/Q Quiet mode. No display output.
/ R : file Read user restrictions from the specified file.
10 Show only users over the specified limit.
/V Verbose output. Include information on individual files.
Display the access (A), creation (C) or last written (W)
date stamp.
/ N : nn Display only the largest nn files per user.
/ X : nn Display only files at least nn bytes long.
The DISKUSE command compiles disk usage statistics by file owner. DISKUSE can
only be used on NTFS volumes. The specified directory dir is scanned and a
Alphabetical Listing of Commands 2 77
report compiled of disk space usage by individual user name. The /S switch
includes subdirectories in dir in the scan.
The compressed sizes of files are always used for the computations. Normally,
DISKUSE computes the disk space used for all users. The / U switch computes the
disk usage for the specified user only. Specify the user in normal
DOMAIN\Username format.
The switch sends D IS KUSE output to the specified file. The / E switch sends
/F
D ISKUSE error output to the specified file. These switches generate file output
in addition to display output. When the / T switch is used, the output generated
by the / F switch differs from the display output. The / Q switch suppresses dis
play output and only file output is generated.
The IT switch generates output in table format. Output to the display in this
mode is space delimited. Output to a file (using the / F switch) is comma delim
ited. The comma-delimited output can be processed by a FOR command or read
into a spreadsheet for further analysis.
The / R switch reads the specified fil e for a list of per-user disk space limits.
The file must be a text file containing one user limit per line. The first item on
the line must be the user name (in DOMAIN\Username format) . The second
item, offset from the first by spaces, must be the threshold size, in bytes, for
that user. If the / R switch is used, the / 0 switch limits the report to users who
exceed their specified threshold.
The /V switch adds verbose file information to the output, listing all files
owned by each user. The / D switch specifies which time stamp to display in this
listing. The / N switch displays only the largest nn files for each user, while the
I X switch displays only files nn bytes or larger.
DOS KEY
Manages command editing, history, and macros.
Syntax:
1. DOSKEY / REINSTALL [ / LISTSIZE=size ]
2. DOSKEY / H ISTORY
3. DOSKEY / INSERT : /OVERSTRIKE
4. DOSKEY / MACROS [ : ALL : : exename ]
5. DOSKEY / MACROFILE=file
6. DOSKEY [ / EXENAME=exename ] name = [ text ]
278 Part III: Scripting Command Reference
Switches:
/ RE I NSTALL Clears the command history buffer.
/ L I STSIZE Sets the size of the command history buffer.
/ I NSERT Select insert mode for command editing.
/ OVERSTR I KE Select overstrike mode for command editing.
/ MACROS Displays currently defined macros.
/ EXENAME Specifies the executable name for the macro.
/ MACROF I LE Specifies a macro file for macro loading.
The DOSKEY command manages the command editing features of the command
shell, including the command history buffer and command macros. Command
history and macro buffers are maintained on a per-shell, per-application name
basis. Only programs that use line input can access a command history and use
command macros. The command history for a specific application is retained
between invocations of the application, provided the application is started
from the same command shell.
Use DOSKEY ( 1 ) to clear the command history buffer. The / L I STS IZE switch sets
the maximum number of commands saved in the buffer. The / RE I NSTALL switch
clears all history buffers for all applications. Use Alt+F7 to clear the history
buffer for the current application. Use DOSKEY ( 2 ) to display the current history
buffer {or press F7) .
Use DOSKEY ( 3 ) to control the initial insert mode of the cursor. The default is
overstrike mode. The mode can also be toggled during editing by pressing the
Insert key.
Use DOSKEY ( 4 ) to list currently defined macros. By default, macros for the com
mand shell are listed. Use the : ALL option to list macros for all applications, or
: exename to list macros for the specified application. When the :ALL option is
used, the output is generated in a format suitable for use by the / MACRO F I L E
switch.
Use DOSKEY ( 5 ) to load a set of macros from a file. The macros are added to any
already defined. Typically this file is generated by using DOSKEY ( 4 ) and redirect
ing command output to a file.
Use DOSKEY ( 6 ) to define a macro. By default, the macro is defined for the com
mand shell. Alternatively, the / EXENAME switch defines the macro for use by the
application specified by exename. The macro name names the macro command,
while text defines the text to be executed by the command. If text is missing,
the named macro definition is deleted.
Alphabetical Listing of Commands 2 79
The following table shows special characters recognized within the macro com
mand text.
Character Description
$G or $g Command output redirection. Equivalent to the >
redirection symbol.
$G$G or $g$g Command output redirection with append.
Equivalent to the » redirection symbol.
SL or $1 Command input redirection. Equivalent to the <
redirection symbol.
$8 or Sb Pipe redirection. Equivalent to the : redirection
symbol.
$T or St Multiple command separator. Equivalent to the &
symbol.
$$ Use to enter a literal $ character.
$ 1 to $9 Command line arguments to the macro.
$* Represents all command line arguments.
Example:
doskey /macros : all >macfile . mac
doskey /mac rofile=macf ile . mac
doskey ls=dir/w $*
ls c : \winnt
The first two examples show how to create a macro file and then restore it for
later use. The last example (line 3) shows how to create a new macro com
mand, ls, to output a Unix-like directory listing.
Notes:
Some Windows NT documentation states that DOSKEV macros are not valid
within scripts. This is not true; DOSKEV macros are valid within scripts.
However, macros are not advised in scripts, as they may not always be avail
able when the script is executed.
Under MS-DOS, the DOSKEV command loaded a TSR to perform command edit
ing. Under Windows NT, the editing features are built into the operating sys
tem, and the DOSKEV command merely provides a means to control these
features.
DOSKEV can be used to create simple scripts. First, use DOSKEV / R E I NSTALL to clear
the history buffer. Then enter and execute the script commands. Then save the
commands as a prototype script using DOSKEV / MACROS, redirecting the output to
a new script file.
280 Part III: Scripting Command Reference
DUM P E L [ R K ]
Dumps a formatted event log.
Syntax:
1 . DUMPEL / L log [ / E nn ] [ / F filename ] [ / M name [ / R ) ] [ / S computer ] [ /T : / C J
[ / NS ] [ / FORMAT fmt )
2 . DUMPEL / B / L logfile [ / E nn ] [ / F filename ] ( / M name [ / R ) ] [ I T : / C ] [ I NS ]
[ / FORMAT fmt ]
Switches:
/L Specifies l og or logfile to dump.
/B Dump a logfile.
/ E nn Filter for event ID nn.
/F fil ename Dump output to filename.
/M name Filter for events logged by specified name .
/R Reverses /M name filter.
I S computer Specifies source computer for log.
IT Delimit dump report using tabs.
IC Delimit dump report using commas.
/ NS Do not dump strings.
/ FORMAT fmt Format the report using fmt.
The DUMPEL command dumps the contents of a Windows NT event log or log
file. The output can be formatted as required, and is suitable for input to a FOR
or F I ND command for further processing.
Use DUMPEL ( 1 ) to dump an event log. The / L switch specifies the log to dump
specify application, system or security. The /S switch specifies the computer
containing the log to dump (the default is the local computer). Use DUMPEL ( 2 ) to
dump an event log file. Event log files are created using Windows NT Event
Viewer. The event log dump is displayed in the console window unless the out
put is redirected to a file, or the I F switch is used.
Normally, the entire log is dumped. The /E switch limits the dump to events
having an event ID of nn. Up to 1 0 / E switches can be specified. The /M switch
limits the dump to events having a source of name , or, if the / R switch is also
specified, to events having a source other than name .
The log dump output consists of one line per event. Normally the fields in the
output are delimited by spaces. The / T switch delimits the fields by tabs, while
Alphabetical Listing of Commands 281
the / C switch delimits the fields b y commas. The fields t o dump for each event
is controlled by the / FORMAT switch. The fmt text specifies the ordering and con
tents of each field. The following table shows all valid characters in fmt.
Valid Character Description
Time of day.
d Date
T Event type.
c Event category.
I Event ID .
s Event source.
u User name.
c Computer name.
s Event string.
This example dumps the application log of the local computer, and restricts the
output to the date, time, event type, and event category.
See also: LOGEVENT
ECHO
Controls command output to console window.
Syntax:
1 . ECHO
2 . ECHO ON : OFF
3 . @ECHO %ECHO%
4 . ECHO text
facilitate this, an ECHO variable is often defined, containing the text ON or OFF
only. Then, placing ECH0 ( 3 ) as the first command in a script toggles command
echo according to the value in this variable.
Use ECH0 ( 4 ) to display text in the console window. Text is always output,
regardless of the state of the echo toggle. Environment variables in text are
expanded normally before the text is output, allowing ECHO ( 4 ) to be used as a
general purpose print command. To avoid confusion with ECH0 ( 1 ) and ECH0 ( 2 ) ,
text cannot be empty, consist only of spaces, or consist only of O N or OFF. To
display an empty line, use a single Tab character for text.
See also: TITLE, NOW
E N D LOCAL
Ends localized scope for environment variable changes.
Syntax:
1 . ENDLOCAL
The ENDLOCAL command, when used in a script file, ends a local scope for envi
ronment variable changes. Any changes made to the environment before an
ENDLOCAL command is executed are lost.
E RASE
See DEL
Alphabetical Listing of Commands 283
EX I T
Exits the current command shell.
Syntax:
1 . EXIT
The EXIT command exits the current command shell, ending the shell session.
The program invoking the shell then continues executing. If the command shell
exiting is the one that started the console window, the window closes.
Notes:
The exit code from the command shell is the most recent exit code from the
last executed program. Thus a nested command shell passes back to its parent
shell the exit code from any program it executes.
See also: CMD, COMMAND
FC
Compares files.
Syntax:
1 . FC /L [ switches ] [ drive1 : J [path 1 J filename1 [ dri ve2 : J [path2J filename2
2 . FC /B [ dri ve 1 : J [path 1 J filename 1 [ dri ve2 : J [path2 J filename2
Switches:
/A Display only first and last line for each difference found.
/B Perform binary comparison.
/C Perform case insensitive comparison.
/L Compare files as ASCII.
/ LBn Set maximum consecutive mismatches to n lines.
/N Display line numbers during comparison.
/T Do not expand tabs into spaces.
/U Compare files as Unicode.
/W Compress whitespace runs for comparison and ignore lead
ing/trailing whitespace.
/ nn Minimum number of lines that must match after mismatch.
The FC command compares files. Files can be compared in two modes:
ASCII/Unicode or binary. Use FC ( 1 ) to compare files in ASCII or Unicode. Use
FC ( 2 ) to compare files in binary. If the files being compared have a file exten
sion of .EXE, .COM, .SYS, .OBJ, .LIB, or .BIN then the default comparison
284 Part III: Scripting Command Reference
F I ND
Filters text files for matching lines.
Syntax:
1 . FIND [ / V J [ / C J [ / N J [ / I J " st ring " [ dri ve : J [ path J filename
2 . FIND [ / V J [ I C ] [ I N ] [ I I ] " st ring "
Switches:
IV Invert test. Displays lines not matching the string.
IC Display only the count of matching lines.
IN Display line numbers of matching lines.
II Ignore case when matching line.
Alphabetical Listing of Commands 285
The FIND command searches and filters text. Text lines are matched against the
specified s tring. Those lines that contain the string are displayed. Those that
do not are discarded.
Use FIND ( 1 ) to filter text from one or more files. The fil ename can contain
wildcards, allowing multiple files to be searched.
Use FIND ( 2 ) to filter text from command input. By default, command input is
all text typed at the console up to the end of file character, Ctrl+Z. Use the
console input redirection symbols to redirect console input from a file or
device. Use the pipe command to send the output of any command to the com
mand input of the FIND command for processing.
The / V switch inverts the sense of the string matching. Instead of displaying
those lines that contain the s tring, the / V switch displays only those lines that
do not contain the s tring. The /C switch displays only a count of the matching
lines, rather than the lines themselves. The / N switch prefixes each displayed
line with the line number in the text file. The I I switch ignores case differences
when searching for s tring in the input lines.
Example:
dir : find / C " <DIR> "
F I NDSTR
Searches for strings in files.
Syntax:
1. FINDSTR [ swi tches ] [ / S J strings [ dri ve : J [path J filename
2. FI NDSTR [ swi tches ] / F : file strings
3. FI NDSTR [ swi tches ] [ / S J / G : s tring [ dri ve : ] [path ] fil ename
4. FINDSTR [ swi tches ] / F : file /G : s tring
5. FI NDSTR [ swi tches ] [ / S J /G : file [ dri ve : ] [path ] filename
6. FI NDSTR [ swi tches ] / F : file /G : file
Switches:
/8 Matches strings if they occur at the beginning of the line.
/E Matches strings if they occur at the end of the line.
IX Matches strings if they exactly match the line.
/L Treat search strings as literal text.
/R Treat search strings as regular expressions (default).
II String matches are case insensitive.
286 Part III: Scripting Command Reference
The / L switch treats search strings as literal strings. In this case, the text speci
fied by string or s trings is matched character for character against text in the
file being searched. By default (or if the /R switch is used), search strings are
treated as regular expressions. Rather than matching literally, FI NDSTR uses each
search string as a template that describes the pattern of text to match. This is
similar to the use of wildcard characters in file names, but more powerful. In a
regular expression, most characters are treated as literal characters and match
exactly the character specified (like a literal search string) . Some characters are
special, however. These are shown in the following table.
Special Character Description
. (dot) Matches any single character.
* Matches the previous character or class any number of
times (including zero) .
Matches the beginning of the line. Similar i n effect t o the
/B switch.
$ Matches the end of the line. Similar in effect to the IE
switch.
[ class ] Ma�ches any character listed between brackets.
[ Aclass ] Matches any character not listed between brackets.
[ x -y ] Matches any character in the range x to y.
\X Escapes the character x to a literal.
\< Matches the beginning of a word.
\> Matches the end of a word.
Example:
findst r " a [ 0 - 9 ] [ 0 - 9 ] * ' * . txt
This example finds all lines containing the letter "a" followed by one or more
decimal digits in all .TXT files in the current directory.
findstr / i ' \ \ \ \ [ a - z0 - 9 \ $ ] ( a - z0 - 9 \ $ ] * \ \ [ a - z0 · 9 \ $ ] [ a - z0 - 9 \ $ ] * ' * . doc
This example finds all lines containing UNC share names in all .DOC files in
the current directory. The 4 backslashes match the \ \ prefix for a UNC name
(two backslashes escaped). The [ a - z0 - 9 \ $ ] part of the match string matches
any letter, digit or literal $ character (allowed characters in a UNC name). The
first occurrence matches one letter, digit, or $. The second occurrence is fol
lowed by an * character, so this matches any number (including zero) of letters,
digits, or $ characters. The following 2 backslashes match a literal backslash.
See also: FIND
288 Part Ill: Scripting Command Reference
FOR
Iterates commands.
Syntax:
1 . FOR ( / D J %var IN (set) DO command
2 . FOR /R ( dri ve : ] [path ] %var IN (set ) DO command
3. FOR /L %var IN (start , step , end) DO command
4. FOR /F [ " opts " ] %var IN (set) DO command
5 . FOR /F [ " opts " ] %var IN ( ' string " ) DO command
6 . FOR /F [ " opts " ] %var IN ( ' cmd ' ) DO command
Switches:
ID Match directory names instead of file names.
/R Recursive directory tree walk.
/L Iterate a numeric series.
/F File token parsing.
The FOR command iterates files, directories, text file lines, command output and
numeric series. For each step in the iteration, the command specified is executed.
The iterator variable, %var, is substituted in the command in a manner similar
to that used for parameter substitution. The iterator variable is named using a
single letter after the percent, such as %i or %n. Note that the iterator variable
name is case sensitive.
When placing a FOR command in a script file, double the % on all references to
the iterator variable. Thus, use %%n instead of %n within a script file. Do not do
this if entering a FOR command directly at the command prompt.
Use FOR ( 1 ) to iterate a set of files or directories. set specifies the files to iterate,
and must be a file name or a wildcard. You can include a drive letter and path
name in set, otherwise the current drive and directory is assumed. By default,
FOR ( 1 ) iterates files. Use the ID switch to iterate directories instead. Parameter
qualifiers can be used in %var to access portions of the file or path name being
iterated (see "Parameter Syntax" ).
Use FOR ( 2 ) to perform a FOR ( 1 ) type iteration on an entire directory tree.
Specify a drive and/or path name as the root of the directory tree to iterate fol
lowing the / R switch. If no drive or path is specified, the current directory is
assumed. FOR ( 2 ) walks the directory tree specified, executing the FOR command
for the specified set in each directory. If set is * . *, all files in the entire tree are
iterated. If set is a single dot, only the directories themselves are iterated.
Use FOR ( 3 ) to perform a numeric iteration. The s tart, step and end values are
numeric values specifying the start value, step amount (increment) and end
value for the iteration. Start and end values are inclusive. Use an end value less
Alphabetical Listing of Commands 289
than a start value, along with a negative step value, to perform a descending
iteration. The iteration ends when the current iterator value in var exceeds the
end value specified.
Use FOR ( 4 ) , FOR ( 5) and FOR ( 6) to parse text files and strings into tokens. FOR ( 4 )
processes each file specified in set as a text file, iterating each line in each file.
Note that, in this case, set is a set of one or more file names separated by
spaces. Wildcards are not allowed.
FOR ( 5 ) processes the text string specified. In this case, the iterated command is
called only once, with the results of the parsing in the iterator variable.
FOR ( a ) processes the output of a command. Enclose cmd in single quotes. The com
mand is executed, and each line of output generated by the command is parsed
before command is executed. This form of the FOR command is very useful, as it
allows the output of commands to be captured and parsed for further processing.
FOR ( 6 ) executes the specified cmd to completion before starting the iteration.
To parse a line of text, the FOR command first breaks the line into tokens. A
token is a portion of an input line delimited by delimiter characters (such as
commas or spaces) . By default, tokens are delimited by space or tab characters
( but see the notes below) . The tokens are then assigned to the iterator variable
or variables. Finally, the specified command is executed. The process then repeats
for the next line. Empty lines are skipped (the command is not executed). The
parsing and tokenizing operation is controlled by the optional opts. If present,
these must be enclosed in double quotes. Individual options in opts are separat
ed by spaces. The following table shows all available options.
Option Description
eol=c Specifies an end of line comment delimiter character.
skip=n Specifies the number of lines to skip at the start of each
text file.
delims=xxx Specifies one or more delimiters to use instead of the
default space and tab.
tokens=x , y , m · n Specifies which tokens on each line are to be placed in
variables for iteration.
The eol option specifies an optional logical end of line character. Text beyond
this character on a line is ignored and not included in any tokens. This is useful
to skip comments when delimited by a character such as semi-colon or pound.
The skip option can be used to skip a number of lines before tokenizing begins.
This is useful when processing command output if the first few lines of output
are headers.
290 Part ill: Scripting Command Reference
The delims option specifies an alternate token delimiter set, instead of the
default space or tab. Each character specified is recognized as a delimiter when
parsing the line. Comma is a common alternative delimiter. The delimiter set
breaks each line of text into tokens. Delimiters themselves are not included in
the tokens.
The tokens option specifies which tokens to include in the iterator variables.
Tokens are numbered starting at 1. You can specify a list of tokens, or a range
separated by a dash. In addition, if the last character of the tokens option is an
asterisk, an additional token is generated that contains all remaining text on
the line not already assigned to other tokens.
The first token on each line, or the lowest numbered token specified by the
tokens option, is placed in the iterator variable %var when the command is execut
ed. If additional tokens are specified by the tokens option, then the FOR com
mand automatically creates additional iterator variables to contain the tokens.
These are named sequentially up the alphabet, starting at the next letter after
%var. The ordering of token indices in the tokens options is not important:
tokens are always assigned from left to right across the command.
Example:
for / r %i in ( * . bm p ) do copy %i c : \ bitmaps
for /1 %i in ( 1 , 1 , 1 0 ) do set ARRAY_%i=0
for /f ' delims= , tokens=1 - 5 " %i in ( " 1 2 , 456 , 777 ' ) do echo %i%j %k%1%m
The last example shows how the FOR command can strip the commas from
numbers. This allows the output of commands that use this format to be
processed so that they can be used with (for example) the SET command.
Notes:
In certain versions of Windows NT, the FOR ( 4) command does not accept tab
as a default delimiter. To overcome this, specify a literal tab character using the
delims= option.
The FOR ( 4 ) command cannot process a file name containing spaces. Instead,
use a FOR ( 6 ) command in combination with a TYPE command. For example,
replace:
for /f %I in ( name wit h spaces . txt ) do echo %I
with
For /f %I in ( ' type " name wit h spaces . txt " ' ) do echo %I
FTYPE
Displays and alters file types.
Syntax:
1 . FTYPE
2. FTYPE fil etype
3 . FTYPE filetype=
4 . FTYPE filetype=text
· The FTYPE command displays and alters file type commands in the registry.
Once a file type is defined you can use the ASSOC command to associate it with
one or more file extensions.
Use FTYPE ( 1 ) to display all current file types, and FTYPE ( 2 ) to display a specific
'
file type. Use FTYPE ( 3 ) to delete an existing file type, and FTYPE ( 4 ) to create a
new type or change an existing type.
The text can be any valid Windows NT executable program and any addition
al required parameters (spaces are allowed) . Always specify the file name of the
executable, including the file extension and (typically) the path name. Within
the text, use \0 or \1 to represent the name of the file being opened. \2
onwards represents additional arguments supplied. You can use \* to represent
all arguments (from \2 onwards), and %- n to represent all arguments starting at
argument n. Generally, \0 or \1 should be enclosed in double quotes to ensure
that file names with embedded spaces are correctly processed.
Example
ftype Text . File=notepad . exe " %1 "
Notes:
File type information and file extension associations are stored in the
HKEY_CLASSES_ROOT section of the registry. Therefore changes made using
the FTYPE command are retained across system shutdowns and affect all users.
See also: ASSOC, ASSOCIATE.
G LOBAL [ RK ]
Displays the names of members of a global group.
Syntax:
1 . GLOBAL groupname domain : \ \computer
The GLOBAL command displays the member list for a specified global group. The
global group is specified using groupname. GLOBAL locates the group either in the
specified domain or on the specified computer.
292 Part III: Scripting Command Reference
Example:
global Administ rators \ \ styx
GOTO
Transfers control to a script label.
Syntax:
1 . GOTO [ : ] label
2 . GOTO : EOF
The GOTO command transfers control to a different location within the script.
GOTO executes a jump to the specified location-no automatic return to the
caller location is possible.
Use GOT0 ( 1 ) to jump to another location in the current script specified by label .
The colon before the label in the GOTO statement is optional. Use GOT0 ( 2 ) to
jump to the end of the current script file. This either terminates the current
script, or (if the script was invoked via a CALL statement) returns to the calling
script.
Example:
goto : exit
: exit
IF
Executes commands conditionally.
Syntax:
1 . IF [ NOT ] ERRORLEVEL level command
2. IF [ NOT ] ( / I ] str1 ==str2 command
3. IF [ NOT ] EXIST fil e command
4. IF [ / I I val 1 op val2 command
5. IF CMDEXTVERSION version command
6. IF [ NOT ] DEFINED varname command
7. IF test ( command) ELSE (command )
Switches:
/I Specifies string comparisons are to be case insensitive.
Alphabetical Listing of Commands 293
Use I F ( 5 ) to test for the command script extensions revision. This test evalu
ates to true if the current script extension revision is greater than or equal to
version. Currently, the command extension revision is 1 . If future versions of
Windows NT alter the script language by adding new features, this value will
be incremented. This allows scripts to verify which syntax and commands are
available and adapt accordingly.
Use I F ( 6 ) to see if a variable is defined. The test evaluates to true if varname is a
defined environment variable. Do not enclose varname in percent symbols.
Use I F ( 7 ) as a variation on any other IF command type to add an ELSE clause.
Replace test with any of the tests described previously. If the test evaluates to
true, the first command in parentheses is executed. If the test evaluates to false,
the second command in parentheses, after the ELSE clause, is executed. Note
that I F ( 7 ) and the ELSE clause are presently undocumented by Microsoft, and
should therefore be used with caution.
Example:
if " \OS!\s ' == " Windows_NT " echo Running on Windows NT
. •
I FMEMB E R [ RK ]
Tests group membership.
Syntax:
1 . I FMEMBER groupname [ . . . ]
The I FMEMBER command checks Windows NT group membership for the current
logged-on user. Specify a list of one or more group names for checking, sepa
rated by spaces. For each group, I FMEMBER checks to see if the current logged-on
user is a member of that group. I FMEMBER then returns a count of the number of
matches as its exit code.
The exit code can be accessed using the IF ERRORLEVEL command and %ERROR ·
LEVEL% variable.
Example:
ifmember Administrators
if not errorlevel 1 exit
This example exits the script if the current user is not an administrator.
Alphabetical Listing of Commands 295
I NSTSRV [ RK ]
Installs or removes a Windows NT service executable.
Syntax:
1 . INSTSRV servicename drive :path\ filename [ ·A acct ] [ · P pwd]
2 . INSTSRV servicename REMOVE
Switches:
·A acct Execute the service using the specified account name.
·P pwd Logon to the specified account name using the specified
password.
The INSTSRV command installs a Windows NT service executable file. Services
are special .EXE files designed specifically to execute as Windows NT services.
They are managed by the service control manager (SCM), and execute indepen
dently of interactive logons.
Use INSTSRV ( 1 ) to install a new service. The service is assigned the specified
servicename, which then appears in lists of services, such as that presented by
Control Panel. The executable for the service must also be specified. Always
include the full drive and path name to the executable file.
The -A switch specifies an account in which to execute the service. If this is not
specified the SYSTEM (also known as the LocalSystem) account is used. The -P
switch supplies a password when logging on using the specified account.
Use INSTSRV ( 2 ) to remove a previously installed service. The .EXE file is not
deleted by this operation.
Example:
instsrv SysMonitor c : \ bi n \ sysmon . exe -a MonitorAccount -p pwd42
KI L L [ R K ]
Kills a process.
Syntax:
1 . KI LL [ · Fl pid
2 . KILL [ · Fl name
Switches:
·F Force the process kill.
296 Part III: Scripting Command Reference
The KILL command kills a Windows NT process. The -F switch forces the
process to be killed.
- ,;
Using the - F flag can result in the loss of unsaved data.
Use KILL ( 1 ) to kill a process by process ID (pid ) . Use Task Manager or PULIST
to obtain process IDs for all processes.
Use KILL ( 2 ) to kill a process by task name or window name. The name can be
either a task name (typically the executable name) or a window name (typically
the applications main window title). In either case, wildcards can be used to
match the name to the process.
See also: PULIST
Labels
Marks a target for control flow transfers.
Syntax:
1 . : label
A label is a line in a script file comprised of a colon followed by a label name.
Valid label names follow the same syntax conventions as file names, except
that spaces are not allowed. Labels must appear at the start of a line, and can
not be part of a compound or multi-line command. Spaces are permitted
before and after the colon character.
The label : EOF is special. If this label is not defined in the script file, it is
assumed to exist at the very end of the file. In this way, the statement GOTO : EOF
means jump to the end of the script and can be interpreted as an " exit" or
"return" statement.
See also: CALL, GOTO
LOCAL [ R K ]
Displays the names of members of a local group.
Syntax:
1 . LOCAL groupname domain : \ \ computer
The LOCAL command displays the member list for a specified local group. The
local group is specified using groupname. LOCAL locates the group either in the
specified domain or on the specified computer.
Alphabetical Listing of Commands 297
Example:
local Administ rato rs \ \ styx
LOGEVENT [ R K ]
Logs an event in the application event log.
Syntax:
1 . LOGEVENT
2 . LOGEVENT [ - M \ \ computer ] [ - S severi ty ] [ - C ca tegory ] text
Switches:
-M Logs event o n specified computer.
-s Log with the specified severi ty.
-c Log event with the specified category.
The LOGEVENT command adds events to the Windows NT application event log.
This allows scripts to record information messages and success/failure results.
This is particularly useful when the script is scheduled via the AT command, as
these scripts typically do not interact with the desktop.
Use LOGEVENT ( 1 ) to install the event log program. This step is necessary on any
computer that is to view the event log information generated by LOGEVENT.
LOGEVENT ( 2 ) also performs the installation step if it detects that LOGEVENT has not
been execute previously.
Use LOGEVENT ( 2 ) to add an event to the event log. The event should be
described using text. The -M switch specifies which computer receives the event
log entry. The default is the local computer. The s switch sets the severity of
-
the event being logged. Severity values are shown in the following table.
Value Description
s Success audit.
F Failure audit.
I Information event.
w Warning event.
E Error event.
Each severity is displayed using a different icon in the event log viewer.
The -C switch includes an optional event category. The category is a numerical
value stored as part of the event. Its meaning is specific to the event being
logged.
298 Part III: Scripting Command Reference
Example:
logevent -s i -c 400 " File write error : log . txt "
LOGO F F [ RK ]
Logs off the current Windows NT session.
Syntax:
1 . LOGOFF [ I F ] [ I N ]
Switches:
/F Force applications to close without saving un-saved data.
/N D o not confirm before logoff.
The command terminates the current Windows NT session. Normally,
LOGOFF
confirms that a logoff is desired and then prompt the user to save
LOGOF F
unsaved data before proceeding. The / F switch forces applications to close
without saving data. The /N switch skips the logoff confirmation request.
MD
See MKDIR.
M KD I R, MD
Creates directories.
Syntax:
1 . MKDIR [ dri ve : ]path
2 . MD [ dri ve : ] path
MORE
Filters text files into pages.
Alphabetical Listing of Commands 299
Syntax:
1 . MORE
2 . MORE / E ( / C ] [ / P ] [ / S ] [ / Tn ] [ +n ]
3 . MORE / E [ / C ] [ / P l ( / S ] [ /Tn ] [ + n ] fil e [ . . . ]
Switches:
/E Enable extended features.
/C Clear screen before displaying page o f output.
/P Expand form-feed characters.
/S Collapse multiple blank lines into one.
/ Tn Expand tabs to column n.
+n Start output at line n.
The MORE command splits text files up into pages. This allows command output
to be viewed that would otherwise scroll off the console window.
Use MORE ( 1 ) or MORE ( 2 ) to filter command input. By default, command input is
all text typed at the console up to the end of file character, Ctrl+Z. Use the
console input redirection symbols to redirect console input from a file or
device. Use the pipe command to send the output of any command to the com
mand input of the MORE command for processing.
Use MORE ( 3 ) to filter one or more text files. File names are separated by spaces.
The / C switch clears the console window before each page is displayed. The / P
switch expands form-feed characters in the input. The / S switch collapses mul
tiple blank lines into a single blank line, compacting the output. The I T switch
expands tabs, setting tab stops at the specified columns. Finally, the +n switch
starts displaying output at line n, skipping earlier lines. For MORE ( 3 ) , only lines
in the first file are skipped.
At the end of each page of output, MORE displays the prompt - More and waits -
for user input. Press any key to continue to the next page. If the I E switch is
used, the following commands can be entered at the prompt.
Command Description
Pn Display next n lines.
Sn Skip next n lines.
F Display next file. Only applicable to MORE( 3 ) .
Q Quit.
Show line number.
? Show help.
Spacebar Display next page.
Enter Display next line.
300 Part III: Scripting Command Reference
Notes:
In some versions of Windows NT, the /T switch does not correctly expand tabs
to spaces.
See also: FI ND, SORT
MOVE
Moves files from one directory to another.
Syntax:
1 . MOVE [ dri ve : ] [path ] filename [ dri ve : ] dstpath
2 . MOVE [ dri ve : ] srcpath [ dri ve : ] dstpath
The MOVE command moves files and directories from one location to another.
Use MOVE ( 1 ) to move individual files to the specified dstpath directory.
Wildcards can be used with filename to move multiple files.
Use MOVE ( 2 ) to move a complete directory to the specified dstpath directory.
The entire directory, including all files and subdirectories, is moved.
Notes:
MOVE operates rapidly when the source and destination drives are the same.
Under MS-DOS, the MOVE command was used to rename directories. Windows
NT uses the REN command to rename directories.
N ET ACCOUNTS
Manages user account database policies.
Syntax:
1 . NET ACCOUNTS [ / DOMAIN ]
2 . NET ACCOUNTS / SYNC ( / DOMAIN ]
3 . NET ACCOUNTS [ swi tches ]
Switches:
/ SYNC Synchronize all account databases.
/ DOMAIN Perform the specified operation on the
domain controller.
/ FORCELOGOFF : nn NO Set number of minutes before forced
logoff occurs.
/MINPWLEN : nn Specifies the minimum password length.
Alphabetical Listing of Commands 301
This example sets the password aging policy such that password cannot be
changed more frequently than once every five days, and expire every 30 days.
The policy is changed in the domain.
See also: NET USERS
N ET COMPUTER
Adds o r deletes computers from a Windows NT domain.
Syntax:
1 . NET COMPUTER \ \ computer /ADD
2 . NET COMPUTER \ \ computer / DEL
Switches:
I ADD Adds specified computer to the domain.
/ DEL Deletes specified computer from the domain.
The NET COMPUTER command manages computer accounts within a domain. The
command is only valid when executed on a Windows NT domain controller.
Use NET COMPUTER ( 1 ) to add a computer to the domain. Use NET COMPUTER ( 2 ) to
delete a computer from the domain. Windows NT workstation and server
computers must become members of a domain to pass logon requests to the
domain controllers in that domain.
Switches:
/AUTODISCONNECT : nn Sets the auto-disconnect time to nn minutes.
/ SRVCOMMENT : " text " Sets the server announce comment to text.
/ H I DDEN : [ YES : NO] Hides or un-hides the server.
The NET CONFIG SERVER command configures the server service. All Windows
NT computers (servers and workstations) provide a server service. Use NET CON
FIG SERVER ( 1 ) to display the current configuration, and NET CONFIG SERVER ( 2 ) to
change the configuration.
The I AUTODISCONNECT switch specifies the numbers of minutes before a remote
session is automatically disconnected. The range is 1 to 65535 minutes, and
the default is 15 minutes. Specify 1 minutes to disable auto-disconnection.
·
Alphabetical Listing of Commands 303
This example hides the computer from other computers browsing the network.
See also: NET V I EW
Switches:
/ CHARCOUNT : nn Sets the number of bytes buffered before data
transmission occurs.
/ CHARTIME : nn Sets the timeout, in milliseconds, before data trans-
mission occurs.
I CHARWAIT : nn Sets the amount of time Windows NT waits for a
device to become available, in seconds.
The N ET CONFIG WORKSTATION command configures the workstation service. All
Windows NT computers (servers and workstations) provide a workstation ser
vice. Use NET CONFIG WORKSTATION ( 1 ) to display the current configuration, and
NET CONFIG WORKSTATION ( 2 ) to change the configuration.
The / CHARCOUNT switch sets the maximum number of bytes buffered by
Windows NT before data is sent to a communications port. The range is 0 to
65,535 bytes, and the default is 1 6 bytes.
The / CHARTIME switch sets the idle timeout period, in milliseconds, before
Windows NT sends data to the communications port. The range is 0 to
65,535,000 ms, and the default is 250 ms.
304 Part III: Scripting Command Reference
The / CHARWAIT switch sets the number of seconds Windows NT will wait for a
communications port to become available. The range is 0 to 65535 seconds,
and the default is 3,600 seconds.
Example:
net config workstation /charwait : 60
NET F I LE
Manages open files on a server.
Syntax:
1 . NET FILE
2. NET FILE id / CLOSE
Alphabetical Listing of Commands 305
Switches:
/CLOSE Closes the specified file.
The NET FILE command manages remotely opened files on a server. Use NET
F I LE ( 1 ) to display a list of all remotely opened files, including each file's unique
id number. Use NET FILE ( 2 ) to force a file to close. Specify the id number for
the file to close.
Closing open files with N ET FILE can result in a loss of file data.
Use NET GROUP ( 1 ) or NET LOCALGROUP ( 2 ) to display a list of all global or local
groups. Use NET GROUP ( 3 ) or N ET LOCALGROUP ( 4 ) to display a list of all members
of the specified group. Global groups can only have user accounts as members.
Local groups can have user accounts and global groups as members.
Use NET GROUP ( 5 ) or N ET LOCALGROUP ( 6 ) to add a new group to the account data
base. The / COMMENT switch adds the specified text as a descriptive comment to
the group.
Use NET GROUP ( ? ) or NET LOCALGROUP ( S ) to delete an existing group. Members of
the group themselves are not deleted, but their membership in the group is
deleted.
Use N ET GROUP ( 9 ) or N ET LOCALGROUP ( 1 0 ) to add or delete group members.
Follow the group name with a list of one or more names to add to the group.
Enclose names containing spaces in double quotes. The I ADD switch adds names
to the group, while the / DELETE switch deletes names from the group. Only user
accounts can by added to global groups, while user accounts or global groups
can be added to local groups.
Example:
net g roup " Power Users " BobM PollyC Ku rtB / add
This example adds three users to the global Power Users group.
See also: ADDUSERS, N ET USERS, GLOBAL, LOCAL, I FMEMBER
N ET LOCALGROU P
See NET GROUP.
N ET NAM E
Manages messenger service names.
Syntax:
1 . NET NAME
2 . NET NAME name ( /ADD ]
3 . NET NAME name / DELETE
Switches:
/ADD Adds the specified name to the name list.
/ DELETE Deletes the specified name from the name list.
The N ET NAME command manages the list of alias names used by the Windows
NT messenger service. These names can be used as target names with the NET
SEND command. In addition to names added using the NET NAME command,
Alphabetical Listing of Commands 307
Windows NT automatically adds the computer name and the interactive user
logon name to the list of available names.
Use NET NAME ( 1 ) to display the list of names currently maintained by this com
puter. Use NET NAME ( 2 ) to add the specified name to the alias list. The /ADD
switch is optional. Use NET NAME ( 3 ) to delete the specified name from the alias
list. Computer names cannot be deleted from the list.
If any computer sends a message via the messenger service, and that message is
sent to a name that appears in the alias name list, the message will appear in a
dialog box on the computer.
Notes:
The Windows NT messenger service must be running on a computer for mes
sages to be received on that computer.
See also: NET SEND
N ET PAUSE
See NET CONTINUE.
N ET SEND
Sends a messenger service message.
Syntax:
1 . NET SEND [ name * : / DOMAIN [ : name ] / USERS ] "message "
Switches:
/ DOMAIN Sends the message to the specified domain.
/ USERS Sends the message to all connected users.
The NET SEND command sends a message to the computers specified. Enclose
the mes sage in double quotes.
The destination can be one of the following:
name Sends the message to the specified computer or user
name, or alias name created via the NET NAME command.
*
Sends the message to all computers in the workgroup.
/ DOMAI N Sends the message to all the names in the domain.
/ DOMAI N : name Sends the message to all the names in the specified
domain.
/ USERS Sends the message to all users remotely connected to this
computer.
308 Part III: Scripting Command Reference
Example:
net send * " Server STYX will be shut down in 1 0 minutes . "
This example sends the message shown to all computers in the workgroup.
Notes:
The Windows NT messenger service must be running on a computer for mes
sages to be received on that computer.
See also: NET NAME
NET SESS I ON
Manages server computer connections.
Syntax:
1 • NET SESSION
2 . NET SESSION \ \ computer
3 . NET SESSION \ \ computer / DELETE
Switches:
/ DELETE Deletes the connection to the specified computer and closes
all open files.
The NET SESS I O N command manages remote computer connections. It can only
be used on Windows NT servers.
Use NET SESS I O N ( 1 ) to display a list of all open connections, and N ET SESS I ON ( 2 )
to display details of open connections from the specified computer. Use NET SES ·
S I O N ( 3 ) to break the connection from the specified computer and close all open
files.
NET SHAR E
Manages printer and directory shares.
Syntax:
1. NET SHARE
2. NET SHARE share
3. NET SHARE share=dri ve : path [ / USERS : n n : / UN L I M ITED ] [ / REMARK : " text " ]
4. NET SHARE share [ / USERS : nn : / U N L IMITED] [ / REMAR K : " text " ]
5. NET SHARE [ share : de vi ce : dri ve : path ] / DELETE
Alphabetical Listing of Commands 309
Switches:
/ USERS Limits maximum number of simultaneous users to nn.
/ U N L I M I TED Allows unlimited users.
/ REMARK Sets share comment to text.
/ DELETE Deletes existing share.
The N ET SHARE command manages shared printers and directories (folders) on
the local computer.
Use N E T SHARE ( 1 ) to display information about all shares defined on the local
computer. Use NET SHAR E ( 2 ) to display detailed information about the specified
share .
Use NET SHARE ( 3 ) to create a new shared directory named share, which maps to
the specified dri ve : path. The / USERS switch limits the number of simultaneous
connections to the share to nn, while the / UN L I M I TED switch (the default) allows
an unlimited number of simultaneous connections. The / REMARK switch assigns a
descriptive comment to the share, which is available when the share is browsed
by a remote computer.
Use to modify the properties of an existing share. Use NET
NET SHARE ( 4 )
to delete a share. Specify the share to delete using either the share
SHARE ( 5)
name, the device name (if the share is a printer share), or the drive and path
name.
Example:
net share cd rom=g : \ / remark : " Local CD - ROM d rive "
This example creates a new share named CDROM that maps to the local path G : \ .
Notes:
Shares names that end in a s character are not displayed when browsing the
local computer from a remote computer.
See also: NET USE, RMTSHARE
NET START
See N ET CONT I NUE.
N ET STAT I ST I CS
Display server and workstation service statistics.
Syntax:
1 . NET STATISTICS SERVER
2. NET STATISTICS WORKSTATION
310 Part III: Scripting Command Reference
The NET STATISTICS command displays statistics about the server or worksta
tion services on a Windows NT computer. Both services normally run on both
Windows NT servers and Windows NT workstations.
Use NET STATISTICS ( 1 ) to display statistics for the server service, and NET STA ·
TISTICS ( 2 ) to display statistics for the workstation service.
NET STOP
See NET CONTINUE.
NET T I ME
Displays and synchronizes to remote computer time.
Syntax:
1 . NET TIME [ /SET]
2 . NET TIME \ \computer [ /SET ]
3 . NET TIME / DOMAIN : name [ /SET ]
Switches:
/ SET Sets the local computer time to that obtained from the
remote computer.
/ DOMAIN Specifies the domain with which to synchronize the time.
The NET TIME command displays the time on a remote computer and optionally
synchronizes the local computer time to that computer.
Use NET TIME ( 1 ) to obtain the time from the computer designated as the time
server for the domain. Use NET TIME ( 2 ) to obtain the time from the specified
computer. Use NET TIME ( 3 ) to obtain the time from the designated time server in
the specified domain.
The / SET switch sets the local computer time to match the time obtained from
the remote computer.
Only Windows NT servers can be designated as time servers. To designate a
server as a time server, add a new Registry value to this key on that server:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanMa
nServer\Parameters
The value to add should be named TimeSource, should have a type of REG_DWORD,
and should have a value of 1 .
Example:
net t ime \ \ server - 1 / set
Alphabetical Listing of Commands 311
This example sets the local computer time to that obtained from the server
SERVER - 1 .
N ET USE
Manages remote connections.
Syntax:
1 . NET USE
2 . NET USE device
3 . NET USE [ device : * I \ \computer\share [password : * I [ / USER : username ]
[ / PERSISTENT : [ YES : NO ] ]
4 . NET USE [ device : * I [password : * ] /HOME
5 . NET USE [ device : * ] / DELETE
6 . NET USE /PERSISTENT : [ YES : NO ]
Switches:
/ USER Specifies the user account to use when connecting
to the share.
/ PERSISTENT Specifies if the connection should persist across
logoff/logon operations.
/ DELETE Deletes the connection.
The NET USE command manages remote connections on the local computer to
shares on remote computers. NET USE maps remote resources, such as shared
directories, to local resources, such as drive letters.
Use NET USE ( 1 ) to display a list of all current connections to remote computers,
and NET USE ( 2 ) to display detailed connection information for the specified
device.
Use NET USE ( 3 ) to map a local device to a remote share. The local device may
be a drive letter, D : through z : , (used when the remote share is a directory) or a
printer, LPT1 : through LPT3 : (used when the remote share is a printer). Specify
an * instead of a device name to automatically use the next available device
name. The remote share to map is specified by the UNC name,
\ \ computer\ share. Use the NET VIEW command to view available network shares.
If the remote share is password protected, specify the password following the
UNC name. Specify an * to make NET USE prompt for a password interactively.
This avoids the need to embed passwords in scripts, where their secrecy may be
compromised. Use the / USER switch to specify a different user account to use
when connecting to the share. The username may include a domain name in the
form DOMAIN \ username .
The / PERSISTENT switch controls the persistence of the connection. Specify
/ PERSI STENT : NO to create a connection which will exist only for the current
3 12 Part ill : Scripting Command Reference
N ET USER
Manages user accounts.
Syntax:
1 . NET USER [ /DOMAIN]
2 . NET USER user [ /DOMAIN ]
3 . NET USER user [password : * I /ADD [ switches ] [ / DOMAIN ]
4 . NET USER user [password : * I [ switches ] [ /DOMAIN )
5 . NET USER user / DELETE [ / DOMAIN )
Switches:
/ DOMAIN Processes accounts in the domain.
/ DELETE Deletes the specified user account.
/ACTIVE : [ YES : NO] Activates or deactivates the account.
/ COMMENT : " text " Adds a descriptive comment to the account.
/ COUNTRYCODE : nnn Specifies the country code for localized
messages.
/ EXPIRES : [ date : NEVER ] Specifies an account expiration date; NEVER
indicates that the account never expires.
I FULLNAME : " name " Specifies the full name of the account.
/ HOMEDI R : path Specifies the home directory for the
account.
/ PASSWORDCHG : [ YES NO ] Allows or disallows password changes by
the user.
Alphabetical Listing of Commands 313
This example creates a new account called P e r ryM with a password of Secret,
and sets the script path to D : \WINNT \ SYSTEM32 \ REPL \ IMPORT \ SCRIPTS \ LOGON . BAT.
See also: NET ACCOUNTS, ADDUSERS
N ET V I EW
Displays available network resources.
Syntax:
1 . NET VIEW [ / DOMAIN [ : name ] ]
2 . NET VIEW \ \ computer
Switches:
/DOMAIN Specifies the domain name for display.
The NET V I EW command views available network resources (directory and print
er shares) .
Use NET V I EW ( 1 ) t o display a list o f server computers i n the local workgroup or
domain. The / DOMAIN switch displays a list of computers in the domain named
name. If name is omitted, the / DOMAIN switch displays a list of available domains.
Use NET V I EW ( 2 ) to display a list of all resources on the specified computer.
Notes:
Only servers which are not hidden are displayed by the NET V I EW ( 1 ) command.
Individual resources with share names ending in a $ character are not displayed
by the NET V I EW ( 2 ) command.
See also: N E T USE
NOW [ R K ]
Displays text with a time stamp.
Syntax:
1 . NOW text
Alphabetical Listing of Commands 315
The NOW command displays the text entered o n the command line prefixed by
the current time and date. NOW ( 1 ) is similar to the ECHO command except for the
date and time prefix.
Example:
now Script execution begun • • •
NTBACKU P
Automatic volume backup.
Syntax:
1 . NTBACKUP EJECT /TAPE : n
3 . NTBACKUP BACKUP paths [ switches ]
Switches:
/A Appends backup sets to the end of the tape.
/V Verifies the backup operation.
/R Restricts access to the tape owner or
administrators.
/ D " text " Specifies a descriptive comment for the backup set.
/B Includes the local registry in the backup operation.
/ HC : [ ON OFF ] Enables or disables hardware compression on the
tape drive.
I T type Specifies the type of backup to perform.
/ L " filename " Specifies a file name for the backup log.
/E Restricts the backup log to exceptions only.
/ TAPE : n Specifies the destination tape drive for the
operation.
The NTBACKUP command provides tape archival facilities for complete volumes
or directory trees. NTBACKUP is a Windows NT GUI application, but it can be
controlled completely from command line switches and is frequently used in
scripts to automate regular backup schedules.
Use NTBACKUP ( 1 ) to eject the tape from the specified drive. Use NTBACKUP ( 2 ) to
initiate a complete backup operation, with optional verify. Specify one or more
paths to backup. Separate individual paths from each other with spaces. Each
path must refer to a local drive or a mapped network drive-UNC names are
not accepted by NTBACKUP. Each path creates a new, distinct, backup set on the
tape.
316 Part III : Scripting Command Reference
The I A switch appends the new backup sets to the end of the tape, preserving
any existing backup sets. If I A is not specified, all existing sets on the tape will
be over-written by the new backup sets. The /V switch performs a verify pass
after the backup operation is complete. All files on the tape are verified against
the original files on disk. Verify results are recorded in the log file and in the
system event log.
The / R switch restricts subsequent access to the backup sets to the tape owner
or an administrator. The /D switch specifies a descriptive comment for all back
up sets. Do not place a space between the switch and the opening double quote.
The /B switch backs up the local registry. This switch is only applicable to
paths that specify the drive containing the Windows NT directory. The / HC
switch controls hardware compression on the tape drive (if this feature is
supported).
The / T switch specifies the type of tape backup operation to perform. Follow
the switch with a space and then one of the types specified in the following
table.
Type Description
normal Back up all files, then clear the archive flag on all
files.
copy Back up all files, but do not clear the archive flags.
inc remental Back up only changed files, then clear the archive
flag on these files.
diffe rential Back up only changed files, but do not clear the
archive flags.
daily Back up only those files changed today, but do not
clear the archive flags.
The / L switch specifies the name of a log file which can be used to record
backup operation results. The /E switch restricts this log file information to
exceptions and errors only.
The / TAPE switch specifies which tape device to use for the backup operation.
Example:
ntbackup backup c : \ Library d: \ Library /v / d " Library Backup" /t normal
Schedule Service is running in an account with sufficient rights to access the dri
ves, directories, and network shares to be backed up. Second, ensure that all
network shares are mapped to the appropriate local drive before starting the
backup operation. The UNCBACK sample script can provide this mapping automat
ically.
Parameter Syntax
Command shell parameter substitution.
Arguments to a script are accessible within the script via script parameters.
Arguments are specified either on the command line or in a CALL statement, and
are separated by spaces, tabs, commas, equal signs, or semi-colons. To pass any
of these characters as part of an argument, enclose the argument in double
quotes. The double quotes enclosing the argument are passed as part of the
argument-the command shell does not strip them.
Parameters are named %n, where n is the parameter index, 0 to 9. The first
argument is passed in parameter %1 , the second in %2 and so on. %0 always con
tains the name of the script file itself (exactly as typed) . Arguments beyond the
ninth are accessed using the SHIFT command. The special parameter %* refers
to all script arguments, exactly as typed, excluding %0.
Parameter names can also be qualified so that only part of the argument is
returned. Qualifiers are placed between the percent sign and the parameter index,
and are prefixed by a tilde. For example, %-fd1 applies the "f" and "d" qualifiers
to parameter 1 . Qualifiers treat the parameter text as a file or path name, and
extract portions of the name. The following table shows all parameter qualifiers.
Qualifier Description
f Expand parameter to a fully qualified path name.
d Expand parameter to a drive letter only.
p Expand parameter as a path only.
n Expand parameter as a file name only.
x Expand parameter as a file extension only.
s Modify n and x qualifiers to refer to the short (MS-DOS)
name.
$var : Treat var as a directory list, and search all directories for the
file specified by the parameter. Then expands to the full path
name of the first match found.
For example, assume that Windows NT is installed in C:\WINNT, that the cur
rent directory is D:\HOME, and that parameter %1 contains XCOPY.EXE. The
following table shows some examples of qualified parameter substitution and
the resulting text.
318 Part III : Scripting Command Reference
Parameter Result
%-f 1 D:\HOME\XCOPY.EXE
%-d 1 D:
%-p1 \HOME\
%-n 1 XCOPY
%-x1 .EXE
%-nx1 XCOPY.EXE
%-$PATH : 1 C:\WINNT\SYSTEM32\XCOPY.EXE
%-dp$PATH : 1 C:\WINNT\SYSTEM32\
Notes:
Qualifiers can also be used with the iterator variables used in FOR commands.
See also: FOR, CALL, CMD, SH I FT
PATH
Sets the command search path.
Syntax:
1 . PATH
2. PATH path
3. PATH ;
4. SET PATH=path
5. SET PATH
The PATH command alters the Windows NT command search path. The com
mand search path is used when the command shell attempts to locate a com
mand for execution. See the START command for more information concerning
the use of the search path.
The command search path is a list of directory names, separated by semi
colons. To locate a command to execute, Windows NT first searches the cur
rent directory, and then searches each directory listed in the search path, in
order, until the executable is located. The current search path is stored in the
PATH environment variable.
Use PATH ( 1 ) or PATH ( 5 ) to display the current search path. Use PATH ( 3 ) to clear
the current search path. This restricts command execution to the current direc
tory only.
Use PATH ( 2 ) or PATH ( 4 ) to set a new search path. You can include %PATH% in the
path specification to add the new path information to the existing path.
Example:
path c : \ bin ; %PATH%
Alphabetical Listing of Commands 3 19
PAUSE
Pauses script execution.
Syntax:
1 . PAUSE
The PAUSE command stops execution of the script command and displays the
prompt Press and key to continue . . Script execution continues when any key
is pressed, except Ctrl+C, which terminates script execution.
See also: SLEEP, CHOICE, T IMEOUT
P ERMCOPY [ R K ]
Copies share permissions.
Syntax:
1 . PERMCOPY \ \srccomputer srcshare \ \dstcomputer dstshare
The PERMCOPY command copies access rights (ACLs) from one share to another,
either on the same or a different server. PERMCOPY cannot copy to or from sys
tem maintained shares (such as C$ ) .
To copy permissions, specify a source computer and share name, and a destina
tion computer and share name.
Example:
pe rmcopy \ \ styx files 1 \ \ arbiter files2
POPD
Restores previously saved drive and directory.
Syntax:
1 . POPD
The POPD command reverses the operation of a PUSHD command by recovering
the most recently saved drive and directory from the save stack.
If the previous PUSHD mapped a UNC name, which resulted in the allocation of a
temporary drive letter, POPD deletes the drive mapping and release the drive letter.
See also: PUSHD, CHO I R
P ROMPT
Sets the command shell prompt.
320 Part III: Scripting Command Reference
Syntax:
1 . PROMPT
2 . PROMPT prompt
3 . SET PROMPT=prompt
4 . SET PROMPT
The PROMPT command alters the Windows NT command shell prompt. This
prompt is displayed when the command shell is ready to accept input, either
from the keyboard or from a script (if echo is on). The current command
prompt is stored in the PROMPT environment variable. Use PROMPT ( 4 ) to display
the current prompt (unless it is set to the default value).
Use PROMPT ( 1 ) to reset the prompt to the system default. This also clears the
PROMPT variable. The default prompt displays the current path and a greater
then symbol, and is equivalent to the prompt string $p$g.
Use PROMPT ( 2 ) or PROMPT ( 3 ) to set a specific prompt. The prompt is set to
prompt, and this value is also set in the PROMPT variable. The prompt argument is
used literally as the prompt. Within this argument you can specify the codes
shown in the following table.
Code Description
$A Ampersand character.
$B Pipe (I) character.
$C Left parenthesis.
$0 Current date.
$E Escape code (ASCII 27).
$F Right parenthesis.
$G Greater than character.
$H Backspace character.
$L Less than character.
$N Current drive letter.
$P Current drive letter and directory path.
$0 Equal sign.
$S Space.
$T Current time.
$V Windows NT version number.
$_ New line.
$$ Dollar sign.
$+ Displays a series of " + " signs, corresponding to the number of
pushed directories on the PUSHD stack. See PUSHD.
$M Displays the remote name (UNC name) for the current drive.
Alphabetical Listing of Commands 321
Notes:
Changing the prompt always changes the PROMPT variable, and vice versa.
PU L I ST [ RK ]
Displays process and user accounts.
Syntax:
1 . PULIST [ \ \computer] [ \ \computer . . . ]
The PUL I ST command displays a list of executing processes on each of the com
puters specified. Processes executing on the local computer are displayed if no
computer names are specified. The list specifies the process executable, the
process ID assigned by the system, and (for the local computer only) the user
name associated with the process.
The process ID can be used as an argument to the KILL command.
See also: KILL
PUSHD
Saves current directory and change to new drive/directory.
Syntax:
1 . PUSHD
2 . PUSHD [ drive : ]path
3. PUSHD • •
4 . PUSHD uncname
The PUSHD command saves the current drive and directory on a stack and
optionally switches to a new drive and directory. The saved drive and directory
can subsequently be restored from the stack using the POPD command.
PUSHD/POPD command pairs can be nested, allowing multiple saved directories to
be stacked up. If $+ is part of the current PROMPT string, the nesting depth of
pushed directories is indicated by a string of + signs in the command prompt.
Use PUSHD ( 1 ) to save the current drive and directory. This is useful before call
ing another script that can alter the drive and/or directory. After calling the
script, use POPD to restore the drive and directory.
Use PUSHD ( 2 ) to save the current drive and directory and then change the drive
and directory to that specified by path. The specified path can be absolute
(starting at the root of the drive) or relative to the current directory. Use
PUSHD ( 3 ) to save the current drive and directory and then move one level " up "
the directory tree o n the current drive towards the root. This command i s not
valid at the root of a directory tree.
322 Part III: Scripting Command Reference
Use PUSHD ( 4 ) to save the current drive and directory and then change to the
UNC path specified by uncname . A UNC path takes the form
\\servername\sharename\path. To switch to this directory, PUSHD creates a
temporary drive mapping to map the UNC share onto a drive letter. Temporary
drive letters are allocated starting at Z: and working down the alphabet, skip
ping letters already in use. When a POPD command is executed the drive letter is
un-mapped from the share.
Example:
pushd e : \workdir
pushd \ \ mast e r - serv\ dat a1 \ archiv e \ temp
RD
See RMD I R .
R EG [ R K ]
Manipulates the Windows NT Registry.
Syntax:
01 . REG QUERY [ rootkey\ ] keypath [ \ valuename ] [ \ \computer ] [ / SJ
02 . REG ADD [ rootkey\ ] keypath \ valuename=value [ type ] [ \ \ computer ]
03 . REG UPDATE [ rootkey\ ] keypath \ valuename=value [ \ \ computer]
04 . REG DELETE [ rootkey\ ] keypath [ \ valuename ] [ \ \ computer ] [ / Fl
05 . REG COPY [rootkey\ ] keypath 1 [ \ valuename ] [ \ \computer1 ]
[ro6tkey\ ] keypath2 [ \ valuename ] [ \ \computer2 ]
06 . REG SAVE [ rootkey\ ] keypath filename [ \ \ computer]
07 . REG BACKUP [ rootkey\ ] keypath filename [ \ \computer]
08 . REG RESTORE filename [ rootkey\ ] keypath [ \ \computer]
09 . REG LOAD filename [rootkey\ ] keypath [ \ \ computer]
10. REG UNLOAD [ rootkey\ ] keypath [ \ \ computer]
Switches:
/S Display keys and values fo r all subkeys.
/F Skip delete confirmation.
The REG command manipulates the Windows NT Registry on the specified
computer or (by default) the local computer.
Registry entries are specified using a hierarchy of keys, which are similar to
directories, and values, which are similar to files. Elements in a registry path
are separated by backslashes. The root of the hierarchy is one of the root keys,
which are predefined. Valid root key values are shown in the following table.
Root Key Value
HKLM HKEY_LOCAL_MACHINE, the local machine hive.
HKCU HKEY_CURRENT_USER, the current users hive.
HKCR HKEY_CLASSES_ROOT, the root of the class information.
HKU HKEY_USERS.
HKCC HKEY_CURRENT_CONFIG, the current machine configuration.
When accessing remote computers, only HKLM and HKU root keys are valid.
If the root key is not specified, HKLM is assumed.
Use REG ( 1 ) to query the registry and display key and value information for the
specified keypath. If a valuename is specified, this item is displayed. Otherwise,
all keys and values in the specified keypath are displayed. The / S switch dis
plays values in all subkeys under the key specified. Key names are shown in
brackets in the query output.
Use R EG ( 2 ) to add a new value to the Registry. The value type can be one of the
following types:
REG_SZ A text string (the default type) .
REG_DWORD A 32-bit binary value, entered as a decimal number.
REG_EXPAND_SZ A text string that can contain environment variables
in percent signs. These are expanded when the string
is used.
Use R EG ( 3 ) to update an existing value with new data, and use R EG ( 4 ) to delete
a value or a key. Specifying a key only (no value) deletes the entire key, includ
ing all values and subkeys it contains. The I F switch skips the confirmation
prompt.
Both REG(2) and REG(3) use the backslash character in the value as an
escape. Therefore, to store a literal backslash character, specify a double back
slash ( \ \ ) instead.
Use R EG ( 5 ) to copy a complete key or individual value from one location or
computer to another. Entire trees of keys can be copied using this command.
Use R EG ( 6 ) or R EG ( 7 ) to save a registry key to the specified file. Do not specify a
file extension with filename. Use REG ( B ) to restore a registry key previously
saved using R EG ( 6 ) or R EG ( 7 ) .
324 Part Ill: Scripting Command Reference
Use REG ( 9 ) to load a registry hive at the specified key. This key is created and
the hive is then linked to the registry at this location. The hive is then accessi
ble at the specified location in the registry until it is unloaded. Use REG ( 1 0 ) to
unload a previously loaded hive.
Example:
reg add HKLM \ Software \AcmeCorp \WonderApp \V1 . 0 \ LoadDir=c : \ apps REG_SZ
reg delete HKLM\ Software \AcmeCorp \WonderApp /f
REM
Comments.
Syntax:
1 . REM text
The REM command provides comments in a script file. The command performs
no actions. The command shell ignores any text entered as part of the REM
command.
REN, RENAM E
Renames files and directories.
Syntax:
1 . REN [ drive : ] [path ] filename1 filename2
2 . REN [ dri ve : ] path 1 path2
3 . RENAME [ dri ve : ] [path ] filename 1 filename2
4 . RENAME [ drive : ]path 1 path2
The REN command renames a file or directory. The RENAME command is a syn
onym for the REN command.
Use REN ( 1 ) or RENAME ( 3 ) to rename a file. The new file name is specified using
fil ename2. You cannot specify a new drive or directory for the new file name
the REN command cannot move files. Wildcards are allowed for both fil ename 1
and fil ename2, allowing multiple renames. The wildcards in the source and des
tination should correspond, so that valid file names are formed when renaming
the file.
Use REN ( 2 ) or RENAME ( 4 ) to rename a directory. The new directory name is spec
ified using path2. You cannot specify a new drive for the new directory-the
REN command cannot move directories. Wildcards are allowed for both path 1
and path2, allowing multiple renames. The wildcards in the source and destina
tion should correspond, such that valid directory names are formed when
renaming the file.
Alphabetical Listing of Commands 325
To ensure source and destination wildcard names correspond, make sure that
the wildcard characters occur at the same location in the source and destina
tion names.
See also: MOVE
R E NAME
.See REN.
R E P LACE
Replaces files with updated versions.
Syntax:
1 . REPLACE [ drive1 : ] [path 1 ] filename [ dri ve2 : ] [path2 ] [ IA : IU] ! / P l [ I R ] [ /W]
2. REPLACE [ dri ve1 : ] (path 1 ] filename [ dri ve2 : ] [path2] IS [ I P] [ I R ] [ IWJ [ IU ]
Switches:
IA Add new files to destination directory.
IP Prompt for confirmation before all operations.
/R Allow replacement i f destination file i s read only.
/W Prompt for a key press before copying files.
IS Replace all files i n all subdirectories o f the destination.
/U Only replace files that are older than the source.
The REPLACE command searches for and updates files in the destination (path2)
with files in the source (path 1 ) . The source filename can use wildcards. If no
destination is specified, the current directory is assumed. The destination must
be a directory, not a file name.
Use REPLACE ( 1 ) to replace files in the specified destination. Each source file that
also exists in the destination is copied to the destination, over-writing the file
replaced. The I A switch adds source files that do not exist in the destination.
The IU switch updates files in the destination that are older than the corre
sponding source file.
Use REPLACE ( 2 ) to replace files in an entire directory tree. For each source file,
REPLACE searches the destination directory tree for any matching file names. For
each file found, REPLACE copies the source file into the appropriate directory,
over-writing the file. The I U switch updates files in the destination that are
older than the corresponding source file.
The I P switch prompts before each file replacement. The I R switch allows
replacing read only files. The IW switch prompts for a key press before starting
the replace operation.
326 Part Ill: Scripting Command Reference
Example
replace c : \ s rc e : \ dist ribution /s / u
RMD I R, RD
Deletes directories and their contents.
Syntax:
1 . RMDIR [ /SJ [ /Q ] [ drive : ]path
2 . RD [ /SJ [ /Q ] [ drive : ]path
Switches:
/s Delete all files and directories in the specified directory.
/Q Quiet mode. Skip confirmation prompt if IS is used.
The RMDI R command deletes directories or directory trees. The RD command is a
synonym for RMD I R .
Specify the directory to delete with path, optionally including a drive letter. By
default, RMDIR will not delete a directory that is not empty.
The / S switch deletes a directory that is not empty. In this case, RMD I R deletes all
files in the directory before deleting the directory itself. If the directory con
tains subdirectories, they are also deleted, and so on down the directory tree.
Use the /S switch with care, as it allows RMD I R to delete entire directory trees in
a single command. RMD I R prompts before proceeding, unless the / Q switch is
used.
Notes:
The RMD I R includes the functionality of the MS-DOS DELTREE command. DEL TREE
is not a Windows NT command, although the DELTREE command may work if a
earlier version of MS-DOS or Windows 95 is present in the current path.
See also: DEL
RMTSHAR E [ RK ]
Manages shares on a remote computer.
Syntax:
1 . RMTSHARE \ \computer
2. RMTSHARE \ \computer\share
3. RMTSHARE \ \computer\share= [ drive : ]path [ switches ]
4. RMTSHARE \ \computer\share [ switches ]
5. RMTSHARE \ \computer\share / DELETE
Alphabetical Listing of Commands 327
Switches:
/G Removes access control from share.
/ G user : perm Sets specified permissions for specified user.
/ REMOVE user Removes specified user from access control list for
share.
/ USERS : nn Sets maximum number of simultaneous users to nn.
ROBOCOPY [ RK ]
Replicates file and directory trees.
Syntax:
1 . ROBOCOPY srcpath dstpath [ file [ • • • ] ] [ swi tches ]
Switches:
IS Copies subdirectories, excluding empty ones.
/E Copies subdirectories, including empty ones.
328 Part III: Scripting Command Reference
The file source for ROBOCOPY is srcpath. This can be either a local drive/directo
ry, or a UNC path. Similarly, the destination for ROBOCOPY is dstpath. This can
also be either a local drive/directory, or a UNC path. Both srcpath and dstpath
must specify directory names, not file names.
By default, ROBOCOPY only processes files in the specified srcpath. The IS switch
processes files in subdirectories of srcpath. This allows ROBOCOPY to replicate an
entire directory tree. Use the / E switch instead of t s if ROBOCOPY should also
replicate empty directories.
In addition to copying files, ROBOCOPY generates a report of which files are
copied. The IV switch generates a verbose report, and the /X switch includes
" extra" files in the report. The / ETA switch displays display estimated copy
times while copying files. The / L switch only generates a report-no actual
copying is performed.
Normally, ROBOCOPY copies file contents exactly, including time stamp informa
tion and attributes, except for the archive attribute, which is always set in the
copied file. The /A+ switch sets the specified attributes in the destination files,
and the /A- switch resets the specified attributes in the destination files. The / XA
switch excludes source files that have the specified attributes set. Finally, The
I A switch copies only files that have the archive attribute set, or the /M switch
copies only these files and then resets this attribute in the source files. The /M
switch is the only switch that changes source files in any way.
All command arguments after the srcpath and dstpath that are not switches are
assumed to be file names that are used to specify which files and directories in
the srcpath are to be considered for copying. By default, * . * is assumed, caus
ing ROBOCOPY to copy all files in the source path to the destination (and all files
in all subdirectories, if / S or /E is specified) . Multiple file names can be speci
fied, each of which can be a wildcard.
If the command includes a /XF switch, then all subsequent file names on the
command line are excluded from the file copy operation. For example, the
command:
ROBOCOPY c : \ e : \ * . * / XF * . EXE * . COM
copies all files from C:\ to E:\ except .EXE and .COM files. Similarly, if the
command includes a / XD switch, then all subsequent names are assumed to be
directory names to exclude from the copy. Directory names cannot contain
wildcards. / XF and /XD switches can be mixed on the command to switch
between excluding directory names and file names.
Before copying a file, ROBOCOPY assigns it a category, depending upon the state
of the file and any corresponding file of the same name in the destination.
These categories are shown in the following table.
330 Part III: Scripting Command Reference
Category Description
Lonely A file that exists only in the source.
Same A file that exists in the source and destination. Both files
have identical size and time stamps.
Changed A file that exists in the source and destination, but the desti
nation file has a different size than the source.
Newer A file that exists in the source and destination, but the
source file is newer than the destination.
Older A file that exists in the source and destination, but the
source file is older than the destination.
Extra A file that exists only in the destination.
Mismatched A file exists in the source, but the destination contains a
directory, not a file, of the same name.
By default, after a file has been categorized, ROBOCOPY copies all files that are
lonely, changed, newer or older. The default copying of older files means that
ROBOCOPY can overwrite newer versions of files with older versions, so care must
be used when using the default behavior.
The /XL switch excludes lonely files from the copy. Only files which exist in the
destination will be copied from the source.
The I I S switch includes same files in the copy. Normally this is not needed, but
can be used to force a refresh of the destination from the source.
The / XC switch excludes changed files from the copy. The /XN switch excludes
newer files from the copy, and the / XO switch excludes older files from the
copy. The / XX switch excludes extra files from all processing.
The / XO switch is normally used to prevent older versions of files in the source
from overwriting newer versions in the destination. It can also be used to
implement a bi-directional replication. By executing two ROBOCOPY commands
with the / XO switch, and swapping the srcpath and dstpath in the second com
mand, a given directory tree can be kept fully replicated in both directions. The
/ XO switch must be used carefully, however. During the file copy process, the
destination file temporarily has a time stamp that is newer than the source file.
If the copy operation is interrupted, then a later use of the / XO switch can cause
ROBOCOPY to accidentally over-write the original source file, mistakenly thinking
that the partially copied file is newer than the original.
The / MOVE switch moves files rather than copies them. The / PURGE switch
processes extra and mismatched files. If the / PURGE switch is included (and the
/ XX switch is not present), then ROBOCOPY deletes all extra files found in the des
tination. In addition, all mismatched directories in the destination are deleted,
including their contents. This ensures that the destination is an exact duplicate
Alphabetical Listing of Commands 331
o f the source tree. However, using / PURGE with a mis-entered dstpa th can have
disastrous results, as ROBOCOPY rapidly purges all directories and files in the des
tination. Therefore, use / PURGE with great caution.
Example:
robocopy c : \ e : \ archive \ d r ive_c /e /xo / x n * . bak pagefile . sys
SC [ R K ]
Manages Windows NT services.
Syntax:
01 . SC [ \ \computer] QUERY [ servicename : switches ]
02 . SC [ \ \computer] QC servicename [ switches )
03 . SC [ \ \computer] GETDISPLAYNAME servicename
04 . SC [ \ \computer ] GETKEYNAME servicedisplayname
05 . SC [ \ \computer] ENUMDEPEND servicename
06 . SC [ \ \computer] CREATE servicename [ swi tches ]
07 . SC [ \ \computer) DELETE servicename
08 . SC [ \ \computer] CONFIG servicename [ switches ]
09 . SC [ \ \computer I START servicename [ args )
10. SC [ \ \computer] STOP servicename
11 . SC [ \ \computer] PAUSE servicename
12. SC [ \ \ computer ] CONTI NUE servicename
13. SC [ \ \computer ] INTERROGATE servicename
14. SC [ \ \computer] CONTROL servicename value
Switches:
TYPE= type Type of service. Can be Own, Share, Interact,
Kernel, or Filesys (default is Share).
START= s tart Startup control for the service. Can be Boot,
System, Auto, Demand or Disabled (default is
Demand).
ERROR= error Error severity if service fails. Can be Normal,
Severe, Critical or Ignore (default is Normal).
B I N PATH = path Path name (including drive) to the service exe
cutable or driver file.
GROUP= group Name of service group for this service.
DEPEND= groups List of groups upon which this service depends.
OBJ = account Name of user account for service, or driver object
name for drivers (default is LocalSystem) .
D I SPLAYNAME= name The friendly display name for the service.
332 Part III: Scripting Command Reference
Use the SC ( 6 ) command to create a new service called servicename and the
SC ( 7 ) command to delete a service called servicename. Deleting a service
removes it from the registry, and is not the same as stopping the service. Use
switches with the SC ( 6 ) command to specify (at the minimum) the path to the
service executable. Use the SC ( S ) command to reconfigure a previously created
service.
Use the SC ( 9 ) command to start an installed service. The optional args are
passed to the service as startup arguments. Use the sc ( 1 0 ) command to stop a
service, and the SC ( 1 1 ) command to pause a service. Use the SC ( 1 2 ) command
to resume execution of a paused service. The actual effect of pausing a service
is service dependent. Use the sc ( 1 3 ) command to interrogate the current state
of a service. Use the SC ( 1 4 ) command to send a control code (a decimal value )
to the service. The meaning of control codes is service dependent.
Example:
sc start PlugPlay
sc create NewService binpath= c : \ bin \ se rvice \ autotest . exe start= auto
displayname= " New Service "
sc pause NewService
sc \ \ mot h ra query NewService
Notes:
Most sc commands that alter service status require administrator privilege.
See also: SCL IST' I N STSRV ' N ET CONTI NUE
334 Part III: Scripting Command Reference
SC L I ST [ R K ]
Displays services on specified computer.
Syntax:
1 . SCLIST [ / R / S] [ / M computer]
Switches:
/R Displays only running services.
IS Displays only stopped services.
/ M computer Displays services for computer.
The SCL I ST command lists services present on the specified computer, or ( by
default) on the local computer. The / R switch restricts the list to running ser
vices, and the / S switch restricts the list to stopped services.
The list is displayed with one service per line. The first column shows the sta
tus of the service, the second shows the service short name, and the third col
umn the full display name.
See also: sc
SCOPY [ R K ]
Copies files and security information.
Syntax:
1 . SCOPY [ dri ve 1 : ] [path 1 ] [ filename 1 ] [ dri ve2 : ] [path ] [ filename 2 ] [ /O J [ /Al [ / SJ
Switches:
10 Copy owner security information.
IA Copy auditing information.
/S Copy all files in subdirectories.
The SCOPY command copies files from one location to another on NTFS vol
umes. The NTFS security information (if present) for each file is copied with
the file. Security information includes access control lists (ACLs), ownership
information, and auditing information.
Use SCOPY ( 1 ) to copy files. Wildcards can be used for filename 1 . If fil ename 1 is
not present, * . * is assumed. The / S switch copies files in subdirectories as well
as files in the specified directory.
By default, SCOPY copies the access control list of each file as well as file data.
The /0 switch copies file ownership information as well. Use of the / O switch
Alphabetical Listing of Commands 335
SET
Sets environment variables and performs arithmetic computations.
Syntax:
1 . SET
2. SET var
3. SET var=
4. SET var=value
5. SET /A expression
Switches:
/A Evaluates a numeric expression.
The SET command sets the values of environment variables, or performs arith
metic computations.
Use SET ( 1 ) to display the entire list of variables defined in the current environ
ment. Use SET ( 2 ) to display the list of all variables that begin with the var text.
Use to delete an existing variable named var from the environment. Use
SET ( 3 )
to define or redefine a variable named var with the val ue specified.
SET ( 4 )
Expansion of environment variables within val ue occurs before the value is
stored in var. The value can contain equal sign characters, but not it cannot
begin with an equal sign.
Use SET ( 5 ) to evaluate a numeric expression. If the command is entered interac
tively, the numeric result is displayed in the console window. If the command is
part of a script, the result is not displayed. Note that the expression can con
tain assignment operators, allowing numeric results to be assigned to environ
ment variables.
The expression is comprised of operators, variables, and literal numbers.
Literals are can be either decimal (the default), hexadecimal (by prefixing the
literal with Ox), binary ( by prefixing with Ob) or octal (by prefixing with 0).
Take care not to prefix a decimal literal with a leading zero-doing so causes
the literal to be treated as an octal number. The following table shows some
examples of literals.
336 Part III : Scripting Command Reference
Literal Description
123 Decimal literal.
-14 Negative decimal literal.
OxlOO Hexadecimal literal, equal to 25 6 decimal.
OblOOl Binary literal, equal to 9 decimal.
014 Octal literal, equal to 12 decimal.
Variables can also be used in expressions. Percent characters are not required
in the expression; the SET command evaluates the values of variables directly.
Undefined variables are assumed to have a value of zero. Variable values are
evaluated using the same syntax as literals-decimal, hexadecimal, binary and
octal numbers are all valid.
The operators allowed in an expression are shown in the following table. All
operators except the expression separator and unary minus are binary opera
tors-they take two values as arguments. The operators are listed in decreasing
order of precedence.
Operator Description
The operators are shown in order of precedence. Operators at the top of the
list are evaluated before those lower in the list. This means that 1 +2*3 is evalu
ated as 1 + ( 2 *3 ) , yielding 7. Parentheses can be used to override this evaluation
order.
The % operator is the modulus operator. The expression A % B computes the
integer remainder when A is divided by B.
The « and » operators perform logical bitwise shift operations. The expres
sion x « N logically shifts all the bits in x left by N bits by adding N zero bits
onto the right of x. For example, 1 2 « 1 yields 24. The expression x » N logi
cally shifts all the bits in x right by N bits by deleting N bits from the right of x.
For example, 1 3 » 1 yields 6. The « and » operators must be escaped to
Alphabetical Listing of Commands 337
avoid conflict with the redirection commands. Use ' > ' > or '<'< to enter these
operators. This is also true for the «= and »= assignment operators.
The bitwise logical operators & (AND), : (OR) and ' (exclusive OR) combine
the bits in their two arguments according to the boolean AND, OR and exclu
sive OR functions. Since the characters &, : and ' are all command syntax
characters, these operators must be escaped using a ' character when entered
in shell scripts. Therefore use '&, ' : and " to enter these operators. This is also
true for the &=, : = and '= assignment operators.
The = operator is the basic assignment operator. The left of the = operator must
be a variable name. The result of the expression on the right is stored, as a dec
imal result, in the specified variable.
The extended assignment operators, such as +=, *= etc, are a shorthand way of
writing an expression such as X=X+4. This expression can be re-written using the
+= assignment operator as X+=4.
The expression separator operator, " , ", allows multiple expressions to be eval
uated using a single SET command. Separate each expression by a comma.
Typically, the expressions are assignment expressions. When the SET command
is typed at the console, the last (right-most) expression result is displayed.
Example:
set VARARGS= 1 4 , 1 5 , 1 6
set DI RCMD= / w
set / a X= ( I * 1 4 ) + ( B << 1 ) + ( C '& 0b1 1 00 )
set / a X=4 , Y=5 , Z=1 0
Notes:
An expression that is comprised only of a single variable name, with no other
operators or literals, is not always evaluated correctly. Instead of SET t A x, use
SET I A X+0 as a workaround. This appears to be a shell bug.
SET LOCAL
Begins localized scope for environment variable changes.
Syntax:
1 . SETLOCAL
2 . SETLOCAL ENABLEEXTENSIONS DISABLEEXTENSIONS
338 Part III: Scripting Command Reference
The SETLOCAL command, when used in a script file, begins a local scope for
environment variable changes. Any changes made to the environment after a
SETLOCAL command is executed are local to the script.
SH I FT
Accesses additional command arguments.
Syntax:
1 . SHI FT
2 . SHI FT /n
Switches:
/n Parameter index from which to start shifting (such as /2).
The SH I FT command accesses command arguments beyond the first nine
entered. The standard parameter syntax ( % 1 , %2, and so on) provides direct
access to only nine command arguments. The shift command provides access
to additional arguments by shifting the arguments down the parameter list.
The first argument is discarded.
Use S H I FT ( 1 ) to shift all arguments one place in the parameter list. The argu
ment in parameter %0 is discarded and replaced by the argument from % 1 . The
Alphabetical Listing of Commands 339
SHUTDOWN [ R K ]
Initiates Windows NT shutdown on the specified computer.
Syntax:
1. SHUTDOWN \ \computer [ / R ] [ /T : nn ] [ / Y ) [ / C J message
2. SHUTDOWN /L [ / R ) [ / T : nn ) [ / YI [ / C ] message
3. SHUTDOWN \ \ comput er /A
4. SHUTDOWN / L /A
Switches:
IL Shuts down local computer.
IA Aborts shutdown.
IR Restarts computer after shutdown.
/ T : nn Sets timeout to nn seconds.
/Y Forces confirmation for all questions.
/C Forces applications to close (can result in data loss).
The SHUTDOWN command initiates the shutdown of a Windows NT computer.
After the specified timeout interval, the Windows NT computer will shutdown
normally.
Use SHUTDOWN ( 1 ) to shutdown the specified computer remotely. Use SHUTDOWN ( 2 )
to shutdown the local computer. Use SHUTDOWN ( 3 ) or SHUTDOWN ( 4 ) to abort the
shutdown. Shutdowns can only be aborted during the specified timeout period.
The /R switch forces a restart after the shutdown is complete. The /T switch
sets the timeout period before the shutdown starts to nn seconds. The /Y switch
assumes a yes response to all questions asked by SHUTDOWN.
The /C switch forces a shutdown at a computer regardless of the state of run
ning applications. Use this switch with caution, as it forces applications to
close without saving data first. This can result in data loss.
340 Part III: Scripting Command Reference
Example:
shutdown \ \ MOTHRA IT : 45
SLEEP [ RK]
Pauses execution for a specified period of time.
Syntax:
1 . SLEEP nn
The SLEEP command pauses command execution for nn seconds and then con
tinues. This is useful when waiting for asynchronous operations to complete.
Example:
sleep 4
SOON [ R K ]
Executes a scheduled command in the near future.
Syntax:
1 . SOON [ \ \ computer] [ delay ] [ / INTERACTIVE ] " command "
2 . SOON I D
3 . SOON I D [ I L : nn ] [ / R : nn ] [ / I : ON : I I : OFF]
Switches:
/ I NTERACT IVE Allows the scheduled command to interactive with
the desktop.
ID Modify or display default settings.
/L Set default local machine delay.
/R Set default remote machine delay.
/I Set default interactive switch.
The SOON command schedules a command to execute via the Windows NT
scheduler in the near future. Executing a SOON command is equivalent to exe
cuting an AT command with the time set to delay seconds in the future.
Use SOON ( 1 ) to schedule a command for execution. The command is executed
on the local computer unless computer is specified. The command is scheduled
to execute delay seconds in the future. If no delay is specified, SOON uses default
values set with the /D switch. The / I NTERACT IVE switch allows the command to
interact with the Windows NT desktop.
Alphabetical Listing of Commands 341
Use SOON ( 2 ) to display the current default values for the local and remote
delays, and the interactive switch. Use SOON ( 3 ) to alter these values. The / L
switch sets the default delay for commands executed locally, and the / R switch
sets the default delay for commands executed remotely. The I I switch sets the
default state of the I I NTERACTIVE switch.
Example
soon \ \ polycrates 300 " copy c : \ logfiles e : \ archives "
Notes:
You can create a script that executes periodically by placing a SOON command
in the script itself. Each time the script executes it schedules another run of the
same script after the specified delay.
See also: AT
SORT
Sorts text lines.
Syntax:
1 . SORT ( / R ) ( / +n )
Switches:
/R Reverses the sort order.
I +n Sorts based on the characters in column n.
The SORT command sorts text lines into alphanumeric order using the ASCII
character set as the collating sequence. SORT reads command input for lines to
sort. By default, command input is all text typed at the console up to the end
of file character, Ctrl+Z. Use the console input redirection symbols to get con
sole input from a file, device, or another command.
The / R switch reverses the sort order. The / +n switch sorts the lines according
to data starting in column n of each line. The first column is numbered 1 .
See also: F I ND, MORE
SRV I N FO [ R K ]
Displays general computer and server information.
Syntax:
1 . SRVINFO [ swi tches ]
2 . SRVINFO [ switches ] \ \computer
342 Part III: Scripting Command Reference
Switches:
/ NS Do not display service information.
/D Display service drivers and services.
/V Display Exchange and SQL information.
/S Display share information.
The SRV I N FO command displays general computer, server, and service informa
tion. Use SRV I N F0 ( 1 ) to display information for the current computer, and SRV ·
I N F0 ( 2 ) to display information for the specified computer.
This example displays the name of the PDC for the domain.
Standard Variables
Standard environment variables defined by Windows NT.
Windows NT defines a number of standard environment variables. These gen
erally provide information on the NT system environment and status of the
machine and current user. Standard environment variables are collected from a
number of sources to form the default environment available to a command
shell when it starts execution.
The sources for standard variables are:
• Special values built-in to the system (such as OS).
• The system environment as defined in Control Panel System (stored in the
Registry).
• The user environment as defined in Control Panel System (stored in the
Registry) .
• Any SET commands in C:\AUTOEXEC.BAT (if parsing is enabled).
• Any S E T commands in a Windows NT logon script.
The following table lists the standard Windows NT environment variables.
Alphabetical Listing of Commands 343
Variable Description
CMDCMDL I N E Command line passed to CMD.EXE, provided no
variable exists of this name.
COMPUTER NAME Network name of the computer, as defined in
Control Panel Network.
COMSPEC Path to Windows NT command shell executable.
ERRORLEVEL Numeric value of last program exit code, provided
no variable exists of this name.
HOMEDRIVE Drive letter corresponding to path of home directory.
HOMEPATH Path to home directory, excluding drive letter.
HOMESHARE UNC name of share if home directory is on a net
work share.
LOGONSERVER Name of server that performed the logon.
NUMBER_OF_PROCESSORS Number of CPUs detected (1 for single CPU
systems) .
OS Specifies the name o f the running O S . Always
"Windows_NT" on Windows NT systems.
PATH A semi-colon separated list of directory names to
search when trying to locate an application to exe
cute (see PATH command) .
PATHEXT A semi-colon separated list o f file extensions t o test
when attempting to locate a command executable
(see START command) .
PROCESSOR_ARCHITECTURE Name of CPU architecture (such as "x86" ) .
PROMPT Defines the format o f the shell command prompt
(see PROMPT command) .
SystemDrive Drive letter o f drive containing Windows NT.
SystemRoot Path (including drive) to Windows NT directory.
USERDOMAIN Name of domain or local machine used to log user
on.
USERNAME Name of user logged on.
USERPROFI LE Path to user profile of current user.
The command shell specially handles the ERRORLEVEL and CMDCMDL I N E variables.
If these variables are defined by a SET command, they behave normally. If,
however, these variables are not defined and they are then expanded in a com
mand, the shell replaces %ERROR LEVEL% with the exit code of the most recently
executed application, and %CMDCMDL I N E% with the exact text of the command line
used to invoke the shell. %CMDCMDL I N E% can be used to access the switches used
to invoke the current command shell.
344 Part III: Scripting Command Reference
Notes:
Some standard variables are not available when executing a scheduled script
via the AT command. Specifically, those which contain information regarding
the current logon session (such as USERNAME ) are not available.
See also: SET, START, CMD
START
Executes a command in a new window or console window.
Syntax:
1 . START [ " titl e " I [ swi tches ] command [ args ]
2 . START [ dri ve : ] path
Switches:
/ Dpath Sets the current drive and directory for the
command to path.
/I Initializes the environment from the initial
environment used by this command shell.
/MIN or / MAX Starts the new command window minimized
or maximized.
/ SEPARATE or / SHARED Starts a 1 6-bit Windows application in a
shared (default) or separate memory space.
Ignored for other application types.
/ LOW, / NORMAL, / H IGH or Specifies the priority class for the command.
/ R EAL TIME The default is / NORMAL.
/WAIT Waits for the application to terminate before
continuing.
/B Executes command without creating a new
window.
The START command starts a new application or executes a command in a new
console window. Any valid application or command can be executed using the
START command, including built-in shell commands, scripts, 1 6-bit Windows
applications, 32-bit Windows applications, console applications, POSIX and
OS/2 applications.
Use START ( 1 ) to execute a command. If the command is a script command or
script file, then a new command shell is started to execute that command. This
shell is started with the / K switch. This means that the new console window
remains active when the command has finished executing, allowing command
output to be viewed. To over-ride this behavior, use START to explicitly execute
Alphabetical Listing of Commands 345
CMD, the command shell, and then submit the command to this shell using the
JC switch.
ti tle specifies the title of the new command window. This is also displayed in
the Windows NT task bar. The title is ignored for Windows applications,
which provide their own title text. The ID switch specifies a starting drive and
directory for the application.
Normally, the new application or command inherits the environment of the
command shell executing the START command. The / I switch makes the com
mand inherit the environment exactly as it was when the command shell began
operation. Changes to the environment made within the command session are
not passed to the new application.
The / M I N and / MAX switches control the position of the new window created for
the application. Without these switches, Windows NT creates a new, normal,
window for the application. The / M I N switch starts the application with a mini
mized window (just a new entry on the task bar). The / MAX switch starts the
application with a maximized window.
If the application specified by command is a 1 6-bit Windows 3 .x application, the
/ SHARED switch specifies that the application is started in the shared memory
space used by 1 6-bit applications. (This is the default. ) The / SEPARATE switch
starts the application in a new address space. Using / SEPARATE increases robust
ness if the application crashes, but can use additional resources while the appli
cation executes.
The / LOW, / NORMAL, / H IGH and / R EALTIME switches control the priority class for
the application. The default priority class is normal, which should be used for
the majority of applications. Use low priority if you want the application to
execute as a background task when Windows NT is not busy. Use high priority
to execute the application as an urgent task, ahead of other regular applica
tions. Use the real-time priority only for ,special real-time applications.
Incorrect use of the real-time priority can cripple a Windows NT system. Use
the priority switches (except I LOW) with restraint, as they interfere with
Windows NT ability to correctly balance system loads.
Without the /WAIT switch, the START command begins execution of the specified
application or command and then immediately completes-the START command
does not wait for the application to complete. With the /WAIT switch the START
command waits until the application terminates before completing.
The /B switch applies only to script and console commands, not Windows
applications. The / B switch executes the specified command within the current
console window, rather than in a new console window. The command is exe
cuted under the control of a new command shell, and this shell is started with
346 Part III: Scripting Command Reference
the / K switch. Therefore, when the command completes, the new shell is still
running. Use the EX IT command to exit this shell and return to the original
shell.
If the first token of command is the exact text CMD, then this is replaced by the
contents of the COMSPEC variable. This ensures that the correct command
shell is executed, and allows the token CMD to act as a placeholder for whichev
er command shell is specified with the COMSPEC variable.
If the first token in command does not specify an explicit file extension, then the
START command uses the PATH EXT variable as a list of file extensions to test
when searching for an executable file. PATHEXT must contain a list of file exten
sions, separated by semi-colons. START tests each file extension in turn when
trying to locate a command to execute. The default value for PATHEXT is
•COM ; EXE ; BAT ; CMD. When searching for the file to execute, START searches the
• • •
current directory, and then each directory specified by the PATH variable. File
extensions in the PATHEXT are applied first. That is, START first checks the current
directory for all possible file extensions, then searches the first entry in the PATH
for all possible PATHEXT file extensions, then the second entry in PATH and so on.
Use START ( 2 ) to start a copy of Windows NT Explorer in the drive and directo
ry specified.
Example:
start /de : \ database /i /low /min cmd /c cleanup . bat
SUBST
Creates virtual drive mappings.
Syntax:
1 . SUBST
2 . SUBST dri ve 1 : [ dri ve2 : ] path
3 . SUBST dri ve 1 : I D
Switches:
ID Deletes virtual drive mapping.
The SUBST command creates virtual drives by mapping a drive letter to an arbi
trary location in a directory tree on a local drive. Once mapped, the virtual
drive letter can be used as a shortcut to access the specified drive and path.
Alphabetical Listing of Commands 347
Use to display a list of all currently mapped virtual drive letters. Use
SUBST ( 1 )
SUBST ( 2 ) to create a new virtual drive. Specify the virtual drive to create in
dri ve 1 , which must be an unassigned drive letter. Use dri ve2 and path to specify
the actual path for the virtual drive.
Use SUBST ( 3 ) to delete a virtual drive mapping.
Example:
s u bst v : c : \winn t \ syst em32 \ logfiles
Notes:
The SUBST command implementation was flawed under MS-DOS and Windows
95. It is fully operational in Windows NT.
Drives created using the SUBST command are present only in the current
Windows NT session. They are not persistent.
T I ME
Displays or sets the system time.
Syntax:
1 . TIME
2 . TIME time
3 . TIME / T
Switches:
JT Do not prompt for a new time.
The TIME command displays or sets the system time. Use TIME ( 1 ) to display the
current time and display a prompt asking for the new time. Press Enter only to
leave the time unchanged. Use T I ME ( 2 ) to set a new time directly from the com
mand line. Use T I ME ( 3 ) to display the time only.
See also: DATE
T I M EOUT [ RK ]
Pauses execution for a specified period of time or until a key is pressed.
Syntax:
1 . TIMEOUT nn
The TIMEOUT command pauses for nn seconds and then continues. The com
mand also continues if a key is pressed during the timeout period. This is use
ful when waiting for asynchronous operations to complete.
348 Part ID: Scripting Command Reference
TITLE
Sets the title text of the console window.
Syntax:
1 . TITLE text
The T I TLE command alters the title displayed in the title bar of the console win
dow. This is also displayed in the Windows NT task bar. Use TITLE ( 1 ) to set
the title to text.
TITLE is useful to show the progress of long scripts without having to fill the
console window with distracting output.
See also: ECHO, NOW
TRANSLATE [ R K ]
Translates a Windows NT error code to text.
Syntax:
1 TRANSLATE code
•
TYP E
Displays a text file in the console window.
Syntax:
1 . TYPE [ dri ve : ] [path ] fil ename
The TYPE command displays a text file in the console window. The file contents
are dumped directly to command output for display. Command output redirec
tion can be used to redirect output to a file or device.
Alphabetical Listing of Commands 349
Example:
type readme . txt
USRSTAT [ R K ]
Displays user statistics for a domain.
Syntax:
1 . USRSTAT domain
The USRSTAT command displays a report listing the user name, full name, and
last logon date/time for each user in the specified domain.
Example:
us rstat nevada
Variable Syntax
Environment variable substitution.
Variable substitution is the first operation that occurs after a command is
entered. The shell searches the command text for variable names bracketed by
% signs. For each such name found, the shell deletes the variable name and
replaces it with the current value of the variable. If a pair of % characters sur
round a variable name that is not defined, the name and the percent characters
are not altered in interactive mode. In script mode, the name and the percent
characters are deleted.
The shell also defines two substitute-only variables: %ERROR LEVEL% and %CMDCMD ·
L I N E%. If there is no user variable named ERRORLEVEL in the environment, then
the shell replaces %ERROR LEVEL% with the exit code returned by the most recently
executed command. If there is a user variable of this name, then normal substi
tution occurs. Similarly, if there is no user variable named CMDCMDLINE,
then the shell replaces %CMDCMD L I NE% with the full text of the command line used
to invoke this copy of the shell.
There are several additional ways to modify the variable substitution process.
These are shown in the following table.
Variable Description
%var% Substitutes the value of var for the variable name in the
command. If var is not defined, does not alter the command
text.
%var : str 1 =s tr2% Substitutes the value of var for the variable name in the
command. Before substitution, each occurrence of str1 in
the var is replaced with s tr2.
350 Part III: Scripting Command Reference
%var : s tr 1 =% Substitutes the value of var for the variable name in the
command. Before substitution, each occurrence of str1 in
the var is deleted.
%var : -n% Substitutes the value of var for the variable name in the
command. Substitution of the value of var begins at the nth
character of the value. The first character is numbered 0.
%var : -n , l en% Substitutes the value of var for the variable name in the
command. Substitution of the value of var begins at the nth
character of the value and continues for len characters, or
until the end of the value. The first character is numbered 0.
%var : -0 , l en% Substitutes the value of var for the variable name in the
command. Substitution of the value continues for l en char
acters, or until the end of the value.
Example:
set VAR1 =d : \winnt40 \ syst em32
set VAR2=cmd . exe
echo %VAR1 : \ =/% %VAR2 : -0 , 3%
The output of the ECHO command is d : /winnt40 / system32 cmd . Note the replace
ment of backward slashes by forward ones, and the extraction of the first three
characters from variable VAR2.
See also: Parameter Syntax, Command Syntax, SET
VER
Displays Windows NT version information.
Syntax:
1 . VER
This example uses the parse features of FOR to extract the version number of
Windows NT from the VER command output.
WHOAM I [ R K ]
Displays the current user name and domain name.
Syntax:
1 . WHOAMI
Alphabetical Listing of Commands 351
The WHOAMI command displays the domain name and user name o f the currently
logged in user. The names are displayed in the standard DOMAIN\UserName
format.
Example:
for If " delims= \ tokens=2 " %i in ( ' whoami ' ) do set USER=%1
The user name is available via the USERNAME variable. However, the user can
alter this with a SET command. The example above shows how to obtain the
true user name from the output of WHOAMI .
W I NAT
See AT.
XCAC LS
See CACLS.
XCOPY
Copies files and directories.
Syntax:
1 . XCOPY source [ destination ] [ swi tches ]
Switches:
IA Copies files that have the archive attribute set (modi
fied).
IM Copies files that have the archive attribute set, and reset
the attribute.
ID Copies only files with a source time newer than the des
tination time.
I D : mm · d d - yy Copies files changed on or after the specified date.
IP Prompts before creating each destination file.
IS Copies directories and subdirectories, except empty
ones.
IE Copies directories and subdirectories, including empty
ones.
IV Verifies all copy operations.
IW Prompts for a key press before copying files.
IC Continues even if errors occur.
II Assumes destination is a directory if it does not exist.
352 Part Ill: Scripting Command Reference
The source can be a single file, a wildcard file name, or a directory name. If
source is a directory name, all files in the directory are copied. The destinati on
can be a file name or a directory name. If no destination is specified, the cur
rent directory is assumed. If destination does not exist, XCOPY prompts to
choose between creating a file or directory with the specified name. The I I
switch assumes that the destination is to be a directory. The I P switch prompts
before creating each destination file. The IW switch prompts before starting the
copy. This is useful if the destination specifies removable media, such as a flop
py disk.
By default, XCOPY copies only the files in the source directory. The IS switch
copies files in all subdirectories as well. The I E switch copies empty subdirecto
ries as well as those containing files. The I T switch only copies directories, not
files. Use the I E switch with I T to copy empty directories as well.
The IA switch only copies files that have the archive attribute set (that is, have
been modified since the last backup) . The IM switch copies these files are then
reset this attribute on each source file. The ID switch only copies files when the
source file time and data is newer than the destination file time and date.
Alternatively, specify an explicit time and data with the I D switch to copy only
those files newer than that date. The I H switch copies hidden and system files,
in addition to normal files. Finally, the IU switch only copies files that already
exist in the destination.
The 1 0 switch prevents the display of file name while copying. The IF switch
displays the full source and destination file names during the copy. The I L
switch only displays the file names-no actual file copy operations occur.
Alphabetical Listing of Commands 353
The / K switch copies attributes as well as file data. Normally, XCOPY resets
the attributes on the destination file. The I R switch copies to a destination file
marked read only. The / N switch copies files using short (MS-DOS) file names
only.
The / V switch verifies all file copy operations. The / Z switch copies all files in
restartable mode. In restartable mode, XCOPY tracks the file copy progress in the
destination file so that the copy operation can be restarted. This is used pri
marily when copying files across WAN network connections.
See also: COPY, ROBOCOPY, SCOPY, MOVE, REPLACE
Appendix A
The RCMD Resource Kit Utility
One tool in the Windows NT Resource Kit that is particularly useful is the
RCMD utility. This utility provides a remote command execution facility
for Windows NT servers and workstations. The utility only ships with the
Windows NT Server version of the Resource Kit, although it can be used
with Windows NT workstations or servers in both the client and target roles.
RCMD executes command-line programs (including scripts) on a remote com
puter (the target) and displays the results of these commands on the local
computer (the client) . The command results are displayed in the same console
window on the client used to initiate the RCMD session. Because the com
mand executes on the remote computer, it can access all the local resources on
that computer.
Commands that can be executed remotely are restricted to 32-bit Windows NT
console applications that use the command input, command output and com
mand error output streams only (see Chapter 2). MS-DOS applications, 1 6-bit
and 32-bit Windows applications, and Windows NT console applications that
use cursor positioning cannot be used.
Command Execution
To execute a command on a target computer from a client computer, use the
following syntax:
1 . RCMD \ \ computer command
2 . RCMD \ \ computer
Use RCMD ( 1 ) to execute a single command on the specified target computer. For
example:
rcmd \ \ pythagoras dir c : \
This command will display a directory of all files in the root of drive C: on the
computer PYTHAGORAS.
Use RCMD ( 2 ) to establish an interactive session on the specified target computer.
This starts a command shell on the target computer and displays the shell
prompt locally (on the client). Normal shell commands (including scripts) can
then be entered and executed on the target computer. To terminate the session,
either exit the remote shell using the EX I T command, or press Ctrl+Break to ter
minate the RCMD session.
Appendix A: The RCMD Resource Kit Utility 359
I n this example, the variable VAR is defined i n the local command shell (as
shown by the first ECHO command). However, this variable is not available to
the command shell executing on the target computer-the second ECHO com
mand does not expand %VAR%.
The Command Reference in Part III of this book covers all of the Windows NT
and Windows NT Resource Kit utilities that are typically used in scripts.
However, there are a number of additional command line utilities and tools
that may be useful in some circumstances. These are listed in this appendix.
For a full description of the operation of these commands, consult the
Windows NT and the Windows NT Resource Kit on-line documentation.
AUTOEXNT [ RK ] A service that executes a script when Windows NT boots.
Equivalent to the MS-DOS AUTOEXEC.BAT facility.
COMPREG [ RK ] Compares two registry keys, looking for differences. Useful to
determine differences in system configurations.
COMPACT Provides command-line control of the built-in compression
available on NTFS volumes.
COMPRESS [ RK ] Provides manual file compression. Use the EXPAND command to
restore the original file or files.
DELSRV [ RK ] Deletes an installed Windows NT service.
DHCPCMD [ RK ] Provides command-line control of the Windows NT DHCP
server.
DHCPLOC [ RK ] Locates DHCP servers on the local subnet.
DISKMAP [ RK] Displays information on hard disk partitions, fault-tolerance
setup data and other disk information.
DNSCMD [ RK ] Provides command-line control of the Windows NT DNS
server.
DRIVERS [ RK ] Displays a complete list of all installed Windows NT device dri
vers. Useful to determine which devices are installed.
EXETYP E [ RK] Determines the type of executable represented by a file (script,
1 6-bit Windows application etc.).
362 Part IV: Appendixes
launching, 37
Symbols command search sequence, 39-40
/HIGH switch, 48 file associations, 41-44
/LOW switch, 48 PATH environment variable, 38
/MAX switch, 47 scripting, 44-45
/MIN switch, 47 START command, 45-48
/N ORMAL switch, 48 ARGECHO.BAT, parameter
/REALTIME switch, 48 substitution, 1 6
@ character, stopping echo, 1 6 arguments
@ command, controlling script passing, 1 03- 1 04
procedures
output, 50
DELSYNCFILE, 174
FINDSWITCH, 167
GETARG, 165
A GETSWITCH, 166
PARSECMDLINE, 163
Access environment variables, passing to, 1 13, 152
Control Panel, 68-69 REGDELMIREGDELU, 170
account management commands, REGGETM/REGGETU, 169
241 REGSETMIREGSETU, 167
accounts for users, MAKEUSR.BAT RESOLVE, 171
script, 1 78-1 80, 1 85-1 87 SRAND, 170
ADDUSERS command, 248 STSYNCFILE, 174
ANIMAL.BAT VARDEL, 163
database file example, 23 1 -236 WAITSYNCFILE, 175
interactive text input example, scripts, 1 5- 1 6, 94
23 1 -236 arithmetic operators, basic
applications expressions, 83-85
console, command shells, 20 arrays, indexed/named, 91 -93
control commands, 243
364 assignment operators
D LS macro, 35
MYNAME macro, 36
database file uses, ANIMAL.BAT double quotes, parameters, 97-99
script example, 231 -236 downloading script libraries, 1 45
DATE command, 271 drive, setting for script, PUSHD
deactivating echo, ECHO OFF command, 1 49
command, 1 7 DUMPEL command, 280
DEBUG variable, 1 50
debugging
CHOICE command, 1 73
scripts, TRACE variable, 1 46
E
DEFDIR variable, 71 echo, removing command echo,
DEL command, 1 05, 271 131
deleting ECHO command, 281
files, recursion example, 1 05-106 command shell prompt, 2 1
sync files, DELSYNCFILE controlling script output, 5 1
procedure, 1 74 script chaining, 1 03
delimiters, parsing text into tokens, script nesting, 1 04
1 34
ECHO OFF command, deactivating
DELIMS option, text parser FOR command echo, 1 7
command, 1 36 ECHO variable, script tracing, 1 46
DELM.BAT, recursion example, 1 05 editing, command line, 30
DELM2.BAT, GOTO file deletion, basic character, 30
1 08
command completion, 33
DELSYNCFILE procedure, deleting command history, 3 1 -32
sync file, 1 74 keys, 266
DIR command, 272 template, 3 1
DIRCOUNT command macro, 36 enabling command echo, I F
directories command, 1 7
commands, 244 ENDLOCAL command, 72, 78, 282
iteration, FOR command, 1 3 1 -1 33 environment variables, 342
REPL.BAT replication, 2 1 8 CMDCMDLINE, 82
setting for script, PUSHD COMSPEC, 8 1
command, 1 49 ENDLOCAL command, 78
DIRUSE command, 274 ERRORLEVEL, 82
DISKUSE command, 276 number formats, 85
DOSKEY command, 3 4-3 5, 277 PATH, 8 1
DIRCOUNT macro, 36 PATHEXT, 8 1
EXIT macro, 36 scope, 77
GLOBAL command 369
L M
labels, 296 macros, command
EOF, 108 DIRCOUNT, 36
jumping to specific label, GOTO EXIT, 36
command, 1 07 LS, 35
scripts, 1 06 MYNAME, 36
launching applications, 37 MAI N procedure, 1 1 4-1 1 5, 1 47
command search sequence, 39-40 main script body example, 1 49
file associations, 4 1 -44 MAKEUSR.BAT
PATH environment variable, 38 new user accounts, 1 78-1 80,
scripting, 44-45 1 85- 1 87
START command, 45-48 procedures, 1 80- 1 82
libraries switches, 178- 1 79
downloading, 145 MASTER.BAT, SLEEP script
_LIBSKEL.BAT, 1 5 1 , 1 53 synchronization, 1 26
_MTPLIB.BAT, 145, 1 54-1 56, 1 59 MD command, 298
scripts, 1 1 6- 1 1 7 MKDIR command, 298
LI BSKEL.BAT, script library modes, command shell
template, 1 51 interactive, 20
LOCAL command, 296 script, 20-25
local scope, closing, 1 49 MORE command, filters, 60, 298
LOGEVENT command, 297 MOVE command, 300
logical bit operators, SET MTPLOGON.BAT
command, 86-87 customizing, 20 1
LOGOFF command, 298 logon script sample, 1 99-202
logons multi-line commands, 76-77, 1 24
script sample, MTPLOGON.BAT, multiple
1 99, 20 1 -202 commands, compound commands,
setup, built-in user variables, 67 56-59
loops expressions, SET command, 88
chaining scripts, 1 02 MYNAME command macro, 36
wait, timeout checks, 1 27
LS command macro, 35
3 72 N switch (IN)
N Notepad
script creation, 1 46
N switch (/N), suppressing key simple script example, 9
choices, 1 27 NOW command, 3 1 4
named arrays, syntax, 91 -93 NOW [RK] command, controlling
naming temporary files, script output, 52
GETTEMPNAME procedure, 1 76 NTBACKUP command, 3 1 5
nesting number formats, SET command, 85
command shells, 29 binary (base 2), 85
IF commands, 1 24 hexadecimal (base 1 6), 85
procedures, 1 1 0 octal (base 8) , 85
scripts, 1 03, 1 04 numeric iteration, FOR commandI
variable substitution, RESOLVE 1 33
procedure, 1 7 1
N ET ACCOU NTS command, 300
N ET COMPUTER command, 302
N ET CONFIG SERVER command,
0
302
obtaining
N ET CONFIG WORKSTATION
positional argument, GETARG
command, 303
procedure, 1 65
N ET CONTI N U E command, 304
switch argument, GETSWITCH
N ET FILE command, 304
procedure, 1 66
N ET GROUP command, 305
octal (base 8) numbers, 85
N ET LOCALGROU P command, 305
operators
N ET NAME command, 306
arithmetic, basic expressions, 83-85
N ET PAUSE command, 304
assignment, 87
N ET SEND command, 307
logical bit, 86-87
N ET SESSION command, 308
relational, 1 23
N ET SHARE command, 308
options, text parser FOR command,
N ET START command, 304
1 36
N ET STATISTICS command, 309
Options tab, console window, 1 0
N ET STOP command, 304
outline of basic script, 1 6
N ET TIME command, 3 1 0
output, script, 48
N ET USE command, 31 1
@ command, 50
N ET USER command, 66, 3 1 2
CLS command, 49
N ET VI EW command, 3 1 4
COLOR command, 49
network management commands,
ECHO command, 5 1
244
NOW [RK] command, 52
new user accounts, MAKEUSR.BAT
REM command, 49
script, 1 78-1 80, 1 85-1 87
TITLE command, 50
Procedures 3 73
T u
T switch l/T), timeouts for C HOICE U NCBAC K.BAT, NTBACKUP UNC
command, 1 28 filename support, 206-209
target computer, RCMD command undefined variables, 73-74
execution/install, 358 user
templates accounts
editing, 3 1 MAKEUSR.BAT script, 1 78-180,
LIBSKEL.BAT script library, 1 5 1 185-187
temporary files, naming, management commands, 241
GETTEMPNAME procedure, 1 76 disk space checking,
terminating USRQUOTA.BAT script,
command shells, 29 1 87- 1 89, 1 92- 1 94
script execution, Ctrl+C keys, 1 5 interaction commands, 1 25
text management scripts, 1 77
color, console window options, 1 0, USRQUOTA.BAT
13 procedures, 1 89- 1 9 1
parsing switches, 1 88
iteration, FOR command, user disk space checking, 1 87- 1 89,
134-136 1 92- 1 94
lines into tokens, 134 USRSTAT command, 349
text file editors, script creation, 146
TIME command, 347
Timeout checks, wait loops, 127
TIMEOUT command, script timeout v
pauses, 1 25, 347
TITLE command, controlling script values, returning from procedures,
output, 50, 348 113
tokens, parsing text lines, 1 34 VARDEL procedure, variable
TOKENS option, text parser FOR deletion by prefix, 1 63
command, 1 36-1 37 variables
TRACE variable, debugging scripts, customizing MTPLOGON .BAT
1 46, 1 50 script, 20 1
TRANSLATE command, 348 DEBUG, 1 50
tunneling, environment variables, deleting
79-80 by prefix, VARDEL procedure,
TYPE command, 348 1 63
from Registry, 1 70
ECHO, script tracing, 1 46
380 variables
w
wait loops, timeout checks, 1 27
WAITSYNCFILE procedure, 1 75
WHOAMI command, 350
WINAT command, 251
Windows Notepad, script creation,
146
Windows NT
management scripts, 205
Resource Kit
command line utilities, 361-362
RCMD utility, 357
windows, console window, 9, 1 2