IPAddr

SUMMARY

Often, administrators would like to run software on only their Windows 95 or Windows 98 clients, or their Windows NT Workstation clients. They may not want to run some logon script commands on their Windows NT Server computers or domain controllers. Some of this information comes from Microsoft while other information was gleaned from http://www.robvanderwoude.com.

MORE INFORMATION

Using a simple batch file and a small executable file, you can tell if the client is a:

Copy the following text to a batch file:

  @echo off
  REM Batch file to detect OS
  REM ----------------------------------
  if Windows_NT == %OS% goto WINNT
  echo You are not running Windows NT (Windows 95/98 perhaps?)
  goto END
  
  :WINNT
  gettype.exe
  
  if errorlevel=9 goto FILENOTFOUND
  
  echo You are running Windows NT.
  echo More Specifically:
  echo.
  
  if ERRORLEVEL=8 goto EIGHT
  if ERRORLEVEL=7 goto SEVEN
  if ERRORLEVEL=6 goto SIX
  if ERRORLEVEL=5 goto FIVE
  if ERRORLEVEL=4 goto FOUR
  if ERRORLEVEL=3 goto THREE
  if ERRORLEVEL=2 goto TWO
  if ERRORLEVEL=1 goto ONE
  
  :FILENOTFOUND
  echo.
  echo Gettype not found.
  echo.
  goto END
  
  :EIGHT
  echo Windows NT Enterprise/Terminal Server Non-Domain Controller
  goto END
  
  :SEVEN
  echo Windows NT Enterprise/Terminal Server Domain Controller
  goto END
  
  :SIX
  echo Windows 2000 Server Domain Controller
  goto END
  
  :FIVE
  echo Windows NT Server Domain Controller
  goto END
  
  :FOUR
  echo Windows 2000 Server Non-Domain Controller
  goto END
  
  :THREE
  echo Windows NT Server Non-Domain Controller
  goto END
  
  :TWO
  echo Windows 2000 Professional installation
  goto END
  
  :ONE
  echo Windows NT Workstation
  goto END
  
  :END
  pause


Copy the Gettype.exe file and the batch file to the target workstations and run the batch file.

You can obtain Gettype.exe version 4.0 by installing the Windows 2000 Resource Kit Tools. Gettype.exe works by querying the registry for the installation type and setting the DOS ERRORLEVEL appropriately:

Silent mode can be set with the /s parameter. This tool can also be run against remote computers.

Explanation of Errorlevels

The correct name for errorlevels should be return codes. But since the DOS command to determine the return code is IF ERRORLEVEL, most people use the name errorlevel.

Errorlevels are not a standard feature of every command. A certain errorlevel may mean anything the programmer wanted it to. Most programmers agree that an errorlevel 0 means the command executed successfully, and an errorlevel 1 or higher usually spells trouble. But there are many exceptions to this general rule.

The IF ERRORLEVEL construction has one strange feature, that can be used to our advantage: it returns TRUE if the return code was equal to or higher than the specified errorlevel. This means most of the time we only need to check IF ERRORLEVEL 1 ... and this will return TRUE for every non-zero return code.

To determine the exact return code the previous command returned, we could use a construction like this:



  @ECHO OFF
  IF ERRORLEVEL 1 SET ERRORLEV=1
  IF ERRORLEVEL 2 SET ERRORLEV=2
  IF ERRORLEVEL 3 SET ERRORLEV=3
  IF ERRORLEVEL 4 SET ERRORLEV=4IF ERRORLEVEL 254 SET ERRORLEV=254
  IF ERRORLEVEL 255 SET ERRORLEV=255
  ECHO ERRORLEVEL = %ERRORLEV%


This is perfectly OK if we only have to check, say, 15 consecutive errorlevels. If we need to check every errorlevel, though, there are better alternatives.

By the way, in Windows NT 4/2000/XP this won't work, since the SET command itself will set an errorlevel (usually 0)! However, Windows NT makes it easy by storing the latest errorlevel in the environment variable ERRORLEVEL:
ECHO %ERRORLEVEL%
will display the errorlevel.

The safest way to use errorlevels for all DOS versions is the reverse order check. Start checking the highest errorlevel that can be expected, then check for the one below, etc:

 
  IF ERRORLEVEL 255 GOTO Label255
  IF ERRORLEVEL 254 GOTO Label254IF ERRORLEVEL   2 GOTO Label2
  IF ERRORLEVEL   1 GOTO Label1
  GOTO Label0
  
  :Label255
  (commands to be executed at errorlevel 255)
  GOTO End
  
  :Label1
  (commands to be executed at errorlevel 1)
  GOTO End
  
  :Label0
  (commands to be executed at errorlevel 0, or no errorlevel)
  
  :End

This will result in many more lines of batch code, but at least it will work in any DOS version. In DOS for the rest of us, we can use FOR loops to determine the errorlevel:


  @ECHO OFF
  REM Reset variables
  FOR %%A IN (1 10 100) DO SET ERR%%A=
  
  REM Check error level hundredfolds
  FOR %%A IN (0 1 2) DO IF ERRORLEVEL %%A00 SET ERR100=%%A
  IF %ERR100%==2 GOTO 200
  IF %ERR100%==0 IF NOT "%1"=="/0" SET ERR100=
  
  REM Check error level tenfolds
  FOR %%A IN (0 1 2 3 4 5 6 7 8 9) DO IF ERRORLEVEL %ERR100%%%A0 SET ERR10=%%A
  IF "%ERR100%"=="" IF %ERR10%==0 SET ERR10=
  
  :1
  REM Check error level units
  FOR %%A IN (0 1 2 3 4 5) DO IF ERRORLEVEL %ERR100%%ERR10%%%A SET ERR1=%%A
  REM Modification necessary for errorlevels 250+
  IF NOT ERRORLEVEL 250 FOR %%A IN (6 7 8 9) DO IF ERRORLEVEL %ERR100%%ERR10%%%A SET ERR1=%%A
  GOTO End
  
  :200
  REM In case of error levels over 200 both
  REM tenfolds and units are limited to 5
  REM since the highest DOS error level is 255
  FOR %%A IN (0 1 2 3 4 5) DO IF ERRORLEVEL 2%%A0 SET ERR10=%%A
  IF ERR10==5 FOR %%A IN (0 1 2 3 4 5) DO IF ERRORLEVEL 25%%A SET ERR1=%%A
  IF NOT ERR10==5 GOTO 1
  
  :End
  REM Clean up the mess and show results
  SET ERRORLEV=%ERR100%%ERR10%%ERR1%
  FOR %%A IN (1 10 100) DO SET ERR%%A=
  ECHO ERRORLEVEL  %ERRORLEV%

This example still handles only 255 error levels (that's all there is in DOS), but it can be easily adjusted once you understand the basic principles.

To check errorlevels during batch file development, use COMMAND /Z yourbatch.bat to display the errorlevel of every command executed in MS-DOS 7.* (Windows 95/98 on).

Setting errorlevels

MS-DOS & Windows 9x:

Use ERRORLVL.EXE from OzWoz Software, or SETERLEV.COM 1.0 from Jim Elliott to test batch files that (are supposed to) check on errorlevels. The syntax couldn't be simpler:


  ERRORLVL number
  or
  SETERLEV number

where number can be any number from 0 to 255.

A small Kix "one liner" can be used too:


  EXIT $ErrLev 

If called by a batch like this:

  KIX32 ERRORLEVEL.KIX $ErrLev=23 

it will return an errorlevel 23 (ERRORLEVEL.KIX would be the name of the kix script mentioned above).

Or use CHOICE.COM, available in all DOS 6.* and up versions, to set an errorlevel:


  ECHO 5  CHOICE /C:1234567890 /N 
  and
  ECHO E  CHOICE /C:ABCDEFGHIJ /N 

will both result in errorlevel 5 since both 5 and E are the fifth choice (/C:...) in the corresponding CHOICE commands.

Windows NT 4:

In NT 4 use either


  COLOR 00 
  or
  VERIFY OTHER 2> NUL 

to set an errorlevel 1.

Windows 2000 & XP:

In Windows 2000 & XP a new /B switch has been added to the EXIT command, enabling the batch file to quit with a return code:


  EXIT

Quits the CMD.EXE program (command interpreter) or the current batch script.

  EXIT  [ /B ]  [ exitCode ]

If /B is specified, sets ERRORLEVEL that number. If quitting CMD.EXE, sets the process exit code with that number.

Make batch files automatically prompt to download third party tools

Many batch files available on this site rely on "third party tools", little programs that are not part of the standard Windows distributions. Examples of these (though actually not really third party, since they are from the same manufacturer) are DEVCON and the Resource Kit tools.

Tools like these enable batch files to accomplish tasks that otherwise would have been impossible from the command line. However, when distributing batch files that use these tools, we can only hope that other users also have these tools available. If not, our carefully constructed batch file will fail.

Messages like 'devcon' is not recognised as an internal or external command, operable program or batch file are not very informative to someone who just downloaded and started GetDevDJ.bat.

Can we somehow prevent these error messages? Yes, we can. In some cases, we can even prompt the user to download the missing tools.

Detection

To prevent the error message for missing tools, we need to find a way to check its availability without generating an error message. In Windows NT 4/2000/XP this is easy:


  DEVCON >NUL 2>&1

returns a non-zero errorlevel if DEVCON is not available on the computer. So to detect the missing tool we could use:

  DEVCON >NUL 2>&1
  IF ERRORLEVEL 1 ECHO DEVCON wasn't found, please install it and try again

In this case, however, that won't work. DEVCON itself returns a non-zero errorlevel when invalid (or no) command line arguments are used. So our batch file would always think DEVCON isn't available. Fortunately, passing DEVCON the /? command line switch makes sure an errorlevel 0 is returned. So the following code does work:

  DEVCON /? >NUL 2>&1
  IF ERRORLEVEL 1 ECHO DEVCON wasn't found, please install it and try again

In this case, if DEVCON is available it will return errorlevel 0, if it is not available the command processor will return a non-zero errorlevel. So, what we found so far is: The second requirement may be the hardest: making sure the tool itself returns an errorlevel 0. In case we cannot be sure of that, or in case we aren't even sure if the command processor will return non-zero errorlevels (e.g. Windows 9x), we still have FIND.

FIND can be used to search for a known substring in the screen output of the tool. Suppose a tool called TESTTOOL would always return a non-zero errorlevel, then we could still use FIND to detect its availability by checking for a known word or substring (e.g. "copyrights") in TESTTOOL's screen output:


  (TESTTOOL /? 2>&1)  FIND /I "copyrights" >NUL
  IF ERRORLEVEL 1 ECHO TESTTOOL wasn't found, please install it and try again

Notes: [1] In Windows NT 4 and later, the brackets make sure the command processor continues with the redirection even if TESTTOOL wasn't found. [2] For Windows 9x batch files, you will need to remove the brackets as well as 2>&1 from the code. Removing this redirection, however, will make this code fail if TESTTOOL /? shows the word "copyrights" in standard error instead of standard output!

Download prompt

Once we have detected the tool is missing, we can either display our own error message (e.g. jump to the help screen) or prompt the user for action (e.g. download the tool). I won't go over the jump and error message details, read more on GOTO if you're not yet familiar with it. To prompt the user for download isn't hard to do in Windows 9x/2000/XP. In Windows NT 4 it can be quite a challenge without CHOICE.EXE from the Resource Kit (which is a "third party tool" itself). Read my page on user input for more details. To perform the actual download without user interaction would itself require "third party tools" or another scripting language (e.g. VBScript). That is why I choose to just open the correct download web page instead. It still requires user interaction, but on the other hand it often isn't necessary to modify the download code with every update of the tool. And it is really simple: just use the START command! As an example, the code I use to check DEVCON's availability in Windows 2000/XP is shown here:

  :: Initialise the variables we need
  SET DevconAvailable=
  SET Download=
  
  :: Check if DEVCON.EXE is available and if not, prompt for download
  DEVCON.EXE /? >NUL 2>&1
  IF ERRORLEVEL 1 (
  	SET DevconAvailable=No
  	ECHO This batch file requires Microsoft's DEVCON utility.
  	SET /P Download=Do you want to download it now? [y/N] 
  )
  
  :: Start download if confirmed
  IF /I "%Download%"=="Y" (
  	START "DevCon" "http://support.microsoft.com/default.aspx?scid=kb;EN-US;Q311272"
  	ECHO.
  	ECHO Install the downloaded files and make sure DEVCON.EXE is in the PATH.
  	ECHO Then try again.
  )
  
  :: Abort if DEVCON.EXE is not available yet
  IF "%DevconAvailable%"=="No" GOTO:EOF