In “Scripting with the NT Resource Kit, part 1: The essentials,” I introduced you to three simple commands (Choice, Now, and Shutdown) from the NT Resource Kit and to a utility that allows you to run a batch file when an NT computer starts without having to log on first. This week, I’m going to introduce you to some more simple commands before I start into the heavy stuff. Tlist produces a list of all running processes or “tasks.” Kill can close a process from a script or from the command line (which works for processes that can’t be closed by normal means). Forfiles is a “for…next” type command that works on a selection of files. Logoff allows you to log off from the command line of a script. Logevent puts your own events into the Windows NT Event Log. Logtime logs the progress of your scripts. Freedisk checks that you have enough disk space before copying or moving files.

Tlist lists the tasks that are running on a Windows NT machine. It displays a list of tasks and their associated Process IDs (PIDs).

A typical output from Tlist would be:
0 System Process
2 System
126 ups.exe
127 WinMgmt.exe
143 Wuser32.exe
170 cpqnimgt.exe
168 cqmghost.exe
175 cqmgserv.exe
178 cqmgstor.exe
187 mstask.exe
202 cpqwmgmt.exe
79 EXPLORER.EXE Program Manager
224 launch32.exe
227 hpcron.exe
229 directcd.exe
213 OUTLOOK.EXE Inbox – Microsoft Outlook
348 CMD.EXE MS-DOS Prompt – tlist
If you’re looking for a running batch file or a command called from a batch file, all you’ll see is the task name CMD, followed by a number. If there’s more than one batch file running, you won’t be able to tell which one is which from this list. However, all other processes can be identified by their appropriate names. Use Find to see if a particular task is running (see the example below). Use Awk if you want to pick out a particular task for further processing (see the example under the section on Kill).
TLIST Š find “CMD” && echo CMD is running
Since you’ll be running a CMD whether you’re working on the command line or using a batch file, the above code will always print, “CMD is running.” So, how would you pick out a CMD process—but not the one that you’re running? One way would be as follows:
title 999 & TLIST | awk “/CMD.EXE/{if($NF!=x){print $0}}” x=”999″
I used “title” to give this CMD a unique name. In Tlist, it will appear as:
88 CMD.EXE 999
Now, I can look for CMD.EXE and display all except for the one in which this code is running.

Kill is a command that you can use to stop a task if you can’t stop it by shutting down the associated application. The parameter for this command is either the PID or the process name. The process name can be part of the name or pattern, such as *help*, if you don’t know the full name—but beware! Any other process that contains the same pattern also will be killed. For example, if you have some errant batch files that have been launched via Schedule but have become stuck in a loop, you can close them by writing the following script:
tlist Š awk “/CMD/{system(c $1)}” c=”KILL “The above code will kill all CMD processes that are running at the time, including the one in which you’re running!
You could use the following script to kill the last file that was launched:
tlist Š awk “/CMD/{x=$1}END{system(c x)}” c=”KILL “
You also could write a script to kill all CMD processes except for the last one in Tlist (which also would be the current one). In my description of Tlist, I provided an example of how to write such a script. See if you can modify that example to kill all CMD processes except for the one in which your code will run. Regardless of which method you use and what process you’re trying to kill, you need to know exactly what’s going on with the particular server that you’re targeting in order to make sure that you kill the correct process.
If you’re having difficulty closing a particular application or ensuring that the processes that you want to kill will close, you can specify the -f parameter and force the processes to die.
This command-line tool can be used in a batch file to select files in a folder or tree for batch processing. Forfiles enables you to run a command on—or pass arguments to—multiple files. For example, you could run the Type command on all files with the *.txt extension in a tree. You also could execute every batch file (*.bat) on the C:\ drive with the filename Myinput.txt as the first argument. The syntax is as follows (and Table A contains definitions):
forfiles [-ppath] [-msearchmask] [-ccommand] [-dddmmyy] [-s] [-v]

Table A
-ppath Indicates path to start searching (default folder is current one from which Forfiles is run)
-msearchmask Searches files according to searchmask (default searchmask is *.*)
-ccommand Indicates command to execute on each file (default command is “cmd /c echo @file”;
following variables can be used: @FILE, @PATH, @RELPATH)
-dddmmyy Selects files with a date greater than or equal to ddmmyy
-s Instructs Forfiles to Recurse into subdirectories

Here’s another example:
forfiles -pc:\ -s -m*.bat -c”cmd /c echo @FILE is a batch file”
This line displays:
“filename.bat” is a batch file
for each batch file that it finds. If you try this command, you’ll find that the variables that begin with @ must be in uppercase.

Complementing last week’s command (Shutdown), there’s a Windows NT Resource Kit command that allows a batch file to log off the current user. Use Logoff in unattended installation routines to end the current user session automatically. Along with the autologon registry settings (which I will cover in a later part of this series), Logoff enables your script to log on, perform a task like installation, and log off without any user intervention.

Table Blists the two parameters that can be used with Logoff:

Table B
/f Forces running processes to close, but asks for user confirmation; user is not asked to save unsaved data
/n User will be logged off without confirmation; user will be prompted to save unsaved data

This tool enables you to make entries to the Event Log on a local or remote computer from either the command prompt or a batch file. The Event Log is very useful for storing historical information of the execution of batch programs that are run remotely from logon scripts or with the At command. If you’re running auto-administration or unattended scripts, the use of Logevent allows you to provide a history of the progress and/or a successful conclusion. Storing entries in the event log of other computers allows the data to be collected and examined centrally, if necessary.

In order for the Event Log Viewer to display the entry properly, the application should be installed onto the computer that’s being used to view the event log. Installation is performed automatically when the Logevent program is used for the first time.

The syntax is as follows (and definitions appear in Table C):
logevent [-m \\computername] [-s N|W|C] [-c number] “message

Table C
-m \\computername Specifies a remote computer on which the event will be logged
-s N|W|C Categorizes the severity of the event as Notify, Warning, or Critical
-c Indicates an event id (you make up your own!)
“message” Denotes the message that will be tagged to the event

The following example puts an Information entry into the event log, along with the message “Batch program failed”:
logevent “Batch program failed”
This example puts a Warning entry in the event log on the computer that’s named Master, along with the message “batchfilename Error at line 99!”:
logevent -m \\Master -s W -c 9999 “%0 Error at line 99!”
If you’re running a script via Schedule, not only do you need to know whether it failed or succeeded, you also need to keep a log of how it progresses. That way, if it fails unexpectedly, you can check a log file to see how much had been completed, and you have the options of completing it manually, running it again, or keeping a history of everything that happened.

Logtime assists you in your tasks. The syntax is very simple. There’s just a single parameter: the text that you want displayed against the time. For example:
logtime ” – beginning copy”
run specialcopy.bat
logtime ” – completed copy”
05/27/96 13:14:19 – beginning copy
copied 33 file in 3 directories
05/27/96 13:15:07 – completed copy
When you’re using a non-attended script to copy files between servers, it’s useful to know that you have enough disk space available on the destination drive. Freedisk allows you to check a drive for a minimum amount of free disk space. The syntax of this command is as follows (where x: is the disk drive that you’re checking):
freedisk x: minimum_bytes
If there’s at least “minimum_bytes” of free disk space available, then the command will reply, “OK.” Otherwise, it will respond, “To small!!” (This isn’t a spelling error on my part; it’s what the command actually returns.) Here’s an example:
freedisk d: 128000 ŠŠ echo Not enough space on drive d:
If there’s less than 128 KB on drive D:, you will receive the following reply:
To small!!
Not enough space on drive d:
Of course, in order for this command to become useful to you, you have to know how much space you need.
I don’t know about you, but that spelling mistake is very annoying, and I find both result strings minimalist in the extreme. So, I would change the above code to freedisk d: 128000> nul ŠŠ echo Less than 128KB of disk space on drive d: (which will dump the command’s output and provide a more meaningful result).
Of course, if you were only looking for a result in an unattended script, you wouldn’t be interested in any sort of output except for the result. You’d use:
freedisk d: 128000> nul && xcopy c:\data d:\
The above line would run XCOPY only if there were enough space on D:.

Over the next two weeks, I shall concentrate on more technical commands from the NT Resource Kit. These commands will allow you to perform tasks in scripts that, without the Resource Kit, you could only perform in real time, online, and using the GUI interfaces that are provided with NT.

Richard Charrington’s computer career began when he started working with PCs—back when they were known as microcomputers. Starting as a programmer, he worked his way up to the lofty heights of a Windows NT Systems Administrator, and he has done just about everything in between. Richard has been working with Windows since before it had a proper GUI and with Windows NT since it was LANManager. Now a contractor, he has slipped into script writing for Windows NT and has built some very useful auto-admin utilities.

The authors and editors have taken care in preparation of the content contained herein, but make no expressed or implied warranty of any kind and assume no responsibility for errors or omissions. No liability is assumed for any damages. Always have a verified backup before making any changes.