dcsimg
 

Batch to the Roots!

by ServerWatch Staff

Batch has been part of Microsoft Operating systems since, well almost since the beginning of time. It has always been a script language which could do simple things but lacked the features 'to get things done'. If you wanted more than just simple logon script or automated tasks you had to look elsewhere. In the beginning you either had to write programs yourself or use small utilities to supplement you're scripts. When Windows came to light there was no way to integrate batch with Windows until third parties provided these with utilities like Winbatch.

Wim Verveen

Batch has been part of Microsoft Operating systems since, well almost since the beginning of time. It has always been a script language which could do simple things but lacked the features 'to get things done'. If you wanted more than just simple logon script or automated tasks you had to look elsewhere. In the beginning you either had to write programs yourself or use small utilities to supplement you're scripts. When Windows came to light there was no way to integrate batch with Windows until third parties provided these with utilities like Winbatch. Since then tools like Perl and Kixtart have appeared on the scene to aid in automating simple or more complex tasks. Microsoft has just recently realized that scripting is important after all and provided Windows Script Host, a very powerful tool. But Batch is not Dead yet! Quietly Microsoft has improved Batch in NT and now Windows 2000 significantly. The improvements are known as command extensions and provide the already present functions with extra, sometimes very useful features. What are these extra features? Well that is exactly what I intend to show you.The commands which are of interest to us are the commands SET, IF, FOR en GOTO.

SET

This well-known command is used to create and change environment variables. Some of the environment variables are pre-determined like %COMPUTERNAME% and %USERNAME%. These variables can be very useful in scripts. Additions to SET are:

The set/a and set/p syntax. Set/a enables calculations in batch. Set /p makes it possible to ask the user for input. Something which before only could be accomplshed by using utilities. Another feature which has been added is the use of substitution with commands like %PATH:str1=str2% This command replaces one stringvalue in PATH with another one. Another interesting new feature to SET is a syntax like this one: %PATH:~10,5% This command shows the first 5 characters behind the tenth position in PATH. To ease the use of compound statements the '/v' parameter has been added, before commands like 'for %i in (*) do set LIST=%LIST% %i' couldn't be used because LIST is evaluated before the IF command instead of during execution. By using the /v parameter on the commandline this behaviour has been changed. Last but not least some extra predetermined variables have been added:

Tabel 1: New environment variables

  • %CD% - The current folder.
  • %DATE% - Date.
  • %TIME% - Time
  • %RANDOM% - A random number between  0 and 32767.
  • %ERRORLEVEL% - The current value of ERRORLEVEL
  • %CMDEXTVERSION% - The command extensions version
  • %CMDCMDLINE% - The commandline of the script.

IF

This is a very important function to change the way a script executes on the basis of certain assumptions. It hasn't been significantly expanded but nevertheless contains some interesting extra's

  • IF [/I] string1 compare-op string2 command
  • IF CMDEXTVERSION number command
  • IF DEFINED variable command

The /I parameters let's you ignore Upper and Lowercase in you're script. 'compare-op' means string operators like EQU en NEQ. The defined value checks if a value actually exists and CMDEXTVERSION checks for the version of the extensions just in case the command changes on a future date.

FOR

This is the command which has been the most significantly enhanced. Table 2 shows all the features which have been added. The FOR command has become a very versitile command because of these additions and very handy to perform automated tasks on files or folders.

Table 2 : FOR command extensions

  • /D FOR works on folders instead of files
  • /R traverse through a directory structure and execute the comamnd on every folder.
  • /L This would make FOR behave like we know it form many other languages
  • /F LRead a set of files, a string or command input.

Table 3 : Variable substitution with FOR

Value  replaces %I with

%~I               Expand without quotes
%~fI              Fully qualified path
%~dI             Drive letter
%~pI             Path only
%~nI             Filename
%~xI              Extension
%~sI              Expanded path with short names only
%~aI             File attributes
%~tI              Date/time of the file
%~zI             Filesize
%~$PATH:I   Searches the path for the first file matching %I.

The power of the for command might be best illustrated by some examples:

FOR /R C:\WINNT %%I IN (*.BMP) DO echo Matching images : %%~nI with size : %%~zI bytes

This command searches the \WINNT directory structure and displays all matching files (without extension)

FOR /F "usebackq tokens=1,2 delims==" %%i IN (`set`) DO @echo %%i has value: %%j

The SET command is processed; varables and their values are divided between %i and %j.

These two simple commands should make clear that FOR has become a much more powerfull function than it used to be in the past. The FOR command even can be used from the commandline to quickly perform singleline commands.

Wim Verveen

GOTO

One of the biggest disadvantages in Batch has always been the absence of subroutines. The only way to solve this problem is to create seperate batchfiles and call these as if they were subroutines or trying to keep all the commands on one line. By extending the CALL and GOTO function Batch has been enhanced to accommodate subroutines as is shown by the following example:

 

@echo off
FOR %%i IN ("c:\winnt\*.*") DO call :sub %%i
goto :eof

:sub
if /I "%~x1" NEQ ".EXE" echo %~f1
goto :eof

This script searches the WINNT directory for files without a .EXE extension. The only other way to accomplish a script like this would have been to add the commands on one line with the '|' seperator. This usually creates messy scripts.

An Example

Let's create a script which demonstrates some of the new functionality together. Suppose we want to do a quick scan of our Windows NT network to check for the existence of machines with a SYMBIOS SCSI interface.
A simple way to do this would be to check for the existence of the file SYMC8xx.SYS

@echo off
FOR /F "usebackq tokens=1" %%i IN (`net view`) DO call :getstation %%i
goto :eof

:getstation
REM Find workstations with the net view command and filter all other output.
REM Initiate a search after that.
SET TEST=%1
if "%TEST:~0,2%" EQU "\\" call :checkfile %1
GOTO :EOF

:checkfile
REM Check for SCSI driver
REM Use default shares and directories for the search
if EXIST "%1\c$\WINNT\system32\drivers\symc8xx.sys" ECHO Station %1 has SYMBIOS SCSI
GOTO :EOF

The above script executes our desired action. First we use the command 'net view' to get a list of active stations in our domain. Because the net view command produces some extra data we filter the output to get only lines starting with '\\' and only the first column of data (to get rid of any remarks which might be present after the computername).
Next we feed the computername in a subroutine which checks for the existence of the desired file and displays any positive results. We could enhance the script with a command like 'echo %1 >> stations.log' to create a logfile.

As you can see Batch isn't dead yet and still can have uses where it outperforms more complicated languages.
The power of Batch lies in it's omnipresence in all versions of NT, it's simplicity and the relative ease to create simple scripts. For more complicated tasks however Batch simply isn't up to the task and you should consider other platforms like Windows Script Host.

This article was originally published on Thursday Feb 1st 2001
Home
Mobile Site | Full Site