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.
Using a simple batch file and a small executable file, you can tell if the client is a:
- Windows 95 or Windows 98 client
- Windows NT workstation
- Windows 2000 Professional installation
- Windows NT Server non-domain controller
- Windows 2000 Server non-domain controller
- Windows NT Server domain controller
- Windows 2000 Server domain controller
- Windows NT Enterprise/Terminal Server domain controller
- Windows NT Enterprise/Terminal Server non-domain controller
@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:
- Returns 1 for Windows NT Workstation.
- Returns 2 for Windows 2000 Professional.
- Returns 3 for Windows NT Server non-domain controller.
- Returns 4 for Windows 2000 Server non-domain controller.
- Returns 5 for Windows NT Server domain controller.
- Returns 6 for Windows 2000 Server domain controller.
- Returns 7 for Windows NT Enterprise/Terminal Server domain controller.
- Returns 8 for Windows NT Enterprise/Terminal Server non-domain controller.
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:
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).
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 numberwhere number can be any number from 0 to 255.
A small Kix "one liner" can be used too:
EXIT $ErrLevIf called by a batch like this:
KIX32 ERRORLEVEL.KIX $ErrLev=23it 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 /Nwill 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> NULto 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:
EXITQuits the CMD.EXE program (command interpreter) or the current batch script.
EXIT [ /B ] [ exitCode ]
- /B Specifies to exit the current batch script instead of CMD.EXE. If executed from outside a batch script, it will quit CMD.EXE.
- exitCode Specifies a numeric 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.
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>&1returns 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 againIn 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 againIn 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:
- start the tool without making it actually do anything
- make sure the tool itself returns an errorlevel 0
- redirect its output to the NUL device
- check for a non-zero errorlevel to detect if the tool is missing
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 againNotes:  In Windows NT 4 and later, the brackets make sure the command processor continues with the redirection even if TESTTOOL wasn't found.  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 promptOnce 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