I authored TechNet article Frequently Asked Questions Regarding The Windows 2000 Command Processor:

NOTE: Unfortunately, TechNet uses an automated conversion process to post the document, which resulted in some line wrap, link, and cosmetic problems.

Topics on this Page
down What is the Windows 2000 Command Processor?
down How do I get help on commands?
down How do I create a file name or folder name using the current date (YYYYMMDD)?
down What environment variables are available to CMD.EXE?
down What switches are available for running Regedit.exe at a CMD prompt or in a batch file?
downHow can I delete a Key or Value Name using a filename.reg file?
downWhat other tools are available for using the registry in batch?
downWhat commands can I use in a logon script?
downHow can I perform a procedure on all files in a folder?
downHow do I parse a file name parameter into it downHow do I test / manipulate strings?
down How do I read a file and process the lines of text?
down How do I launch a process at a different priority?
downHow do I display the current directory in the Title bar of a batch files command Windows?
downHow can a batch file alter the size of its' CMD Window?
downHow can I get a batch file to prompt for user input?
downHow can I get a batch file to 'sleep' for n seconds?
downHow can I get a batch file to beep for attention?
downHow do I pipe batch output, including commands and responses, to a log file?
downWhat is delayed environment variable expansion?
down What are the conditional processing symbols?
downHow do I send a pop-up message?
down How do I execute a command in every sub-folder?
down How do I remove all files and sub-directories from a folder, without removing the folder?
down How can I send e-mail from a batch script?
downHow can I retrieve basic user data?
down How can I count the number of lines in a file, and/or display the last n lines?
down How can I create a file containing all the user names in my domain?
down '<Command>' is not recognized as an internal or external command, operable program or batch file?

From: Jerold Schulman, Windows Server MVP - Author of Tips & Tricks.

Newsgroups: microsoft.public.win2000.cmdprompt.admin

Subject: FAQs about the Windows 2000 Command Processor.

Date: July 15, 2002

Summary: Frequently Asked Questions (FAQs) about the use of the Windows 2000 command processor.

Posting-Frequency: Monthly

Last-modified: July 15, 2002

What is the Windows 2000 Command Processor? Back to Top

Answer: Windows 2000 supports two (2) command processors:

- COMMAND.COM is the command processor for the virtual DOS Machine (VDM), used for processing MS-DOS based applications and scripts.

- CMD.EXE is the native 32-bit command processor, used to open a command prompt and to process batch (.bat) files.

This FAQ addresses CMD.EXE. If you need help troubleshooting 16-bit applications, see Microsoft Knowledge Base articles:

Troubleshooting NTVDM and WOW Startup Errors (Q196453).

Troubleshooting MS-DOS-Based Programs in Windows (Q165214)

Troubleshooting 16-Bit Windows Applications (Q103656).

To identify whether any program is 16-bit or 32-bit:

  1. Use Windows Explorer to navigate to the folder that contains the executable (.exe) file.
  2. Right-click the .exe file and press Properties.
  3. The program is probably 16-bit if there is no Version tab. To be sure, create a shortcut from the .exe file. If the shortcut Properties has a Run in separate memory space check box, it is 16-bit.

To identify whether a running program is 16-bit or 32-bit:

  1. Right-click a blank area of the taskbar and press Task Manager.
  2. Select the Processes tab.
  3. Locate the program in the Image Name column.
  4. 16-bit programs run under the virtual DOS Machine (VDM). The program is indented under Ntvdm.exe. Additionally, a 16-bit Windows program has wowexec.exe indented with it. This is the Windows On Windows (WOW) emulator.

How do I get help on commands? Back to Top

Answer: To get help on commands, open a CMD.EXE prompt and type any of the following:

help - To get a list of supported commands.

<Command Name> /? - to get help on <Command Name>. Example: net /?

<Command Name> <Sub Command Name> /? - to get help on the <Command Name> <Sub Command Name>. Example: net user /?

Some commands provide detail help, such as DIR, SET, FOR, IF, etc., while others only provide minimal information, such as NET USER. To get additional help, create a shortcut to a ntcmds.bat file that contains:

@echo off
start hh.exe ms-its:%WINDIR%\Help\windows.chm::/ntcmds.htm

and set it to run Minimized.

How do I create a file name or folder name using the current date (YYYYMMDD)? Back to Top

Answer. To parse the date into its' YYYY, MM, and DD components, we would use the FOR command. When you type Date /T, a typical North American installation would display Day MM/DD/YYYY, like Mon 07/15/2002.

To parse this into the YYYY, MM, and DD components, type:

for /f "Tokens=2-4 Delims=/ " %a in ('date /t') do set mm=%a&set dd=%b&set yy=%c

Note When using the FOR command in a batch file, replace % with %%.

To create a folder named 20020715, type MD %yy%%mm%%dd%.

To create a universal date parser, that works on all Windows NT-based systems (Windows NT 4.0, Windows NT 5.0 (Windows 2000), and Windows NT 5.1 (Windows XP, which doesn't display the Day when using date /t), regardless of date format, we can make use of the fact that when you type Date, a display similar to:

The current date is: Mon 07/15/2002
Enter the new date: (mm-dd-yy)

exhibits the format (mm-dd-yy). Create a batch file, named univdate.bat, in your path, which contains:

@echo off                              set $tok=1-3                              for /f "tokens=1 delims=.:/-, " %%u in ('date /t') do set $d1=%%u                              if "%$d1:~0,1%" GTR "9" set $tok=2-4                              for /f "tokens=%$tok% delims=.:/-, " %%u in ('date /t') do (                               for /f "skip=1 tokens=2-4 delims=/-,()." %%x in ('echo.^|date') do (                                  set %%x=%%u                                  set %%y=%%v                                  set %%z=%%w                                  set $d1=                                  set $tok=))
When you type call univdate, the appropriate environment variables are set. In North America, this would typically be mm, dd, and yy.

What environment variables are available to CMD.EXE? Back to Top

Answer: In addition to the environment variables that are defined using Control Panel / System / Advanced / Environment Variables, Windows 2000 has some built-in variables. To see the environment variables that are available, type SET.

Note The built-in variables are different if you log on locally versus log on to a domain. Notice that %LOGONSERVER% contains the validating domain controller.

Windows 2000 also defines some hidden environment variables that you can use:


Expands to the current directory. If your current folder is %USERPROFILE%\My Documents, @echo %CD% might display C:\Documents and Settings\Jerry\My Documents.


Expands to the same output as typing DATE.


Expands to the same output as typing TIME.


Generates a random integer in the range of 0 - 32767.


Expands to the current ERRORLEVEL.


Expands to the current Command Processor Extensions version number.


Expands to the original command line that invoked the Command Processor.

What switches are available for running Regedit.exe at a CMD prompt or in a batch file? Back to Top

Answer: The Windows NT-based Registry Editor, Regedt32.exe, does NOT support batch or command prompt operations. You can use Regedit.exe, with appropriate switches, to silently Merge a filename.reg file with your registry, or to export a registry file.

To silently Merge a filename.reg file, use the following syntax:

regedit /s <Drive:>\FolderName\FileName.reg

To export a filename.reg file, in Windows NT 5.x format, use:

regedit /e "<Drive:>\FolderName\FileName.reg" "KeyPath"

Note The quote marks are only required if the 'path' contains spaces.

To export a filename.reg file, in W9x/NT4 format, suitable for merging with W9x/NT4/NT5 registries, use:

regedit /a "<Drive:>\FolderName\FileName.reg" "KeyPath"

How can I delete a Key or Value Name using a filename.reg file? Back to Top

Answer: To delete a key, using a filename.reg file, use the following syntax:



Example: To delete the HKEY_LOCAL_MACHINE \Software \McAfee Key, including all sub-keys, and all Value Names, use the following filename.reg file:


\[-HKEY_LOCAL_MACHINE \Software \McAfee\]

Then run:

regedit /s <Drive:>\Folder\FileName.reg

To delete a Value Name, using a filename.reg file, use the following syntax:



Example: To delete the Tweak UI Value Name from the HKEY_LOCAL_MACHINE \SOFTWARE \Microsoft \Windows \CurrentVersion \Run key, use the following filename.reg file:


\[HKEY_LOCAL_MACHINE \SOFTWARE \Microsoft \Windows \CurrentVersion \Run\]
"Tweak UI"=-

What other tools are available for using the registry in batch? Back to Top

Answer: If you install the Support Tools from the Windows 2000 CD-ROM, you can use REG.EXE to Add, Delete, Copy, Compare, Export, Import, Load a Hive, Query, Save, Restore, and Unload a Hive. To install the Support Tools:

  1. Insert the Windows 2000 CD-ROM into your CD-ROM drive.
  2. Click Browse this CD, and then open the Support\Tools folder.
  3. Double-click Setup.exe, and follow the on-screen instructions.

Using REG.EXE, and Netdom.exe from the Support Tools, you can script a report of all the Windows NT-based workstations in your domain, listing the computer name, O/S version, and service pack, and piping the report to C:\report.txt:

@echo off                              setlocal                              if exist c:\report.txt del /q c:\report.txt                              For /f "Skip=1 Tokens=1" %%a in ('netdom query /domain WORKSTATION') do call :computer "%%a"                              endlocal                              goto :EOF                              :computer                              set machine=%1                              set machine=%machine:"=%                              set cv=                              set CSD=                              if "%machine%" EQU "The" goto :EOF                              if "%machine%" EQU "Directory" goto :EOF                              set key="\\%machine%\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion"                              for /f "Skip=3 Tokens=2*" %%i in ('reg QUERY %key% /v CurrentVersion') do set cv=%%j                              if not defined cv goto :EOF                              if "%cv%" LSS "4.0" goto :EOF                              for /f "Skip=3 Tokens=2*" %%i in ('reg QUERY %key% /v CSDVersion') do set csd=%%j                              @echo %machine% %cv% %csd%>>c:\report.txt

What commands can I use in a logon script? Back to Top

Answer: A logon script can use any command supported by the client O/S.

If you have a mixture of Windows NT-based clients and other Windows clients, you can test if the client platform is Windows NT-based by including the following statement:

if "%OS%"

"Windows_NT" goto winnt

If you need to test for a specific operation system, the following commands should work on all Microsoft operating systems:

  1. ver | find "Windows XP" >nul<br>
  3. if not errorlevel 1 goto WXP<br>
  5. ver | find "Windows 2000" >nul<br>
  7. if not errorlevel 1 goto W2000<br>
  9. ver | find "Windows NT" >nul<br>
  11. if not errorlevel 1 goto WNT<br>
  13. ver | find "Windows 98" >nul<br>
  15. if not errorlevel 1 goto W98<br>
  17. ver | find "Windows 95" >nul<br>
  19. if not errorlevel 1 goto W95<br>
  21. ver | find "Windows ME" >nul<br>
  23. if not errorlevel 1 goto WME<br>
  25. ver | find "OEM Service Release" >nul<br>
  27. if not errorlevel 1 goto WOEM<br>
  29. ver | find "MS-DOS" >nul<br>
  31. if not errorlevel 1 goto DOS<br>
  33. ::Unknown<br>
  35. echo ERROR - What are you running?<br>
  37. goto END<br>
  39. :WXP<br><br>
  41. goto end<br>
  43. :W2000<br><br>
  45. goto end<br>
  47. :WNT<br><br>
  49. goto end<br>
  51. :W98<br><br>
  53. goto end<br>
  55. :w95<br><br>
  57. goto end<br>
  59. :WME<br><br>
  61. goto end<br>
  63. :WOEM<br><br>
  65. goto end<br>
  67. :DOS<br><br>
  69. :end<br>

To define the %USERNAME%, %COMPUTERNAME%, and %LOGONSERVER% environment variables on non-Windows NT-based Windows clients, install on all non-Windows NT-based Windows clients. You must also install WINSET.EXE, from the Windows CD-ROM, on these clients. You can then use the following code in your logon script:

if "%OS%"

"Windows_NT" goto winnt
%windir%\putinenv.exe L
%LogonServer%\NetLogon\Winset USERNAME=%USERNAME%
%LogonServer%\NetLogon\Winset LOGONSERVER=%LOGONSERVER%

The most used command in a logon script is net use, used for mapping a drive letter to a share. The syntax is:

net use <:Drive:> \\ServerName\ShareName\[\folder\] /persistent:NO

Note See the NET USE help in the ntcmds.chm file for other options. Windows 2000 can map below a share, but downlevel clients cannot. If you have configured the users home directory, you can use the net use <:Drive:> /home /persistent:NO syntax.

How can I perform a procedure on all files in a folder? Back to Top

Answer: The FOR command will allow us to process multiple lines of command output. We can use the FOR command to pass the results of a DIR to a process.

If we wanted to rename all .txt files in a folder, whose 2nd-4th character of the file name was upper case ABC, to a .log file, we could use the following example.bat file, and pass the folder name as a parameter (example.bat "C:\Documents and Settings\Jerry\My Documents")

@echo off                              setlocal                              if \{%1\}

\{\} goto syntax if not exist %1 goto syntax set folder=%1 ::Set folder as current directory pushd %1 ::Strip quote marks set folder=%folder:"=% for /f "Tokens=*" %%a in ('dir /b /a-d "%folder%\*.txt"') do call :isabc "%%a" ::Return to previous current directory popd endlocal goto :EOF :syntax @echo Syntax: Example FolderPath endlocal goto :EOF :isabc set filename=%1 ::Strip quote marks set filename=%filename:"=% ::Test 2nd position, for a 3 byte string if not "%filename:~1,3%" EQU "ABC" goto :EOF rename %1 *.log

How do I parse a file name parameter into its' constituent parts? Back to Top

Answer: When you invoke a batch file with a parameter (%1), you are able to parse it to extract meaningful information.

Note Command Extensions ( /E:ON ), enabled by default, must be on.


The normal parameter.


expands %1 to a fully qualified path name.


expands %1 to a drive letter only.


expands %1 to a path only.


expands %1 to a file name only (prefix)


expands %1 to a file extension only.


changes the meaning of n and x options to reference the short name.


returns the size of the file, if %1 is a file.

You can use these modifiers in combination:


expands %1 to a drive letter and path only.


expands %1 to a file name and extension only.

To determine where a batch file was run from, use %~dp0

I have scripted demo.bat to display the various parsing of a file/folder name parameter. Demo.bat contains:

  1. @echo off<br>
  3. @echo Batch file: %~dp0<br>
  5. If \{%1\}\{\} @echo No parameter specified&goto :EOF<br>
  7. :loop<br>
  9. If \{%1\}<h1><a name="_goto_EOF_br_echo_br_echo_1_1_br_echo_f1_f1_br_echo_d1_d1_br_echo_p1_p1_br_echo_n1_n1_br_echo_x1_x1_br_echo_s1_s1_br_echo_dp1_dp1_br_echo_nx1_nx1_br_Shift_parameter_string_br_shift_br_goto_loop_br_code_p_p_If_I_type_p_p_code_b_demo_C_Documents_and_Settings_Jerry_My_Documents_My_Pictures_Jerold_jpg_br_SystemRoot_Notepad_exe_userprofile_b_br_code_p_p_b_font_face_courier_demo_bat_font_b_will_display_p_p_code_Batch_file_C_Util_br_br_1_C_Documents_and_Settings_Jerry_My_Documents_My_Pictures_Jerold_jpg_br_f1_C_Documents_and_Settings_Jerry_My_Documents_My_Pictures_Jerold_jpg_br_d1_C_br_p1_Documents_and_Settings_Jerry_My_Documents_My_Pictures_br_n1_Jerold_br_x1_jpg_br_s1_C_DOCUME_1_Jerry_MYDOCU_1_MYPICT_1_Jerold_jpg_br_dp1_C_Documents_and_Settings_Jerry_My_Documents_My_Pictures_br_nx1_Jerold_jpg_br_br_1_C_WINNT_Notepad_exe_br_f1_C_WINNT_notepad_exe_br_d1_C_br_p1_WINNT_br_n1_notepad_br_x1_exe_br_s1_C_WINNT_notepad_exe_br_dp1_C_WINNT_br_nx1_notepad_exe_br_br_1_C_Documents_and_Settings_Jerry_br_f1_C_Documents_and_Settings_Jerry_br_d1_C_br_p1_Documents_and_Settings_br_n1_Jerry_br_x1_br_s1_C_DOCUME_1_Jerry_br_dp1_C_Documents_and_Settings_br_nx1_Jerry_br_code_begin_bookmark_heading_p_p_a_name_k_a_p_table_width_100_cellpadding_0_cellspacing_0_border_0_tr_td_font_face_arial_helvetica_size_2_class_head3_b_class_bold_How_do_I_perform_calculations_b_font_td_td_align_right_valign_bottom_a_href_#top_target__self_img_src_http_www_microsoft_com_technet_images_arrowup_gif_width_9_height_9_border_0_alt_Back_to_Top_a_td_tr_tr_td_colspan_2_bgcolor_#FFCC00_img_src_http_www_microsoft_com_technet_images_spacer_gif_alt_width_1_height_1_border_0_td_tr_table_img_src_http_www_microsoft_com_technet_images_spacer_gif_alt_width_1_height_12_border_0_br_end_bookmark_heading_p_Answer_The_b_SET_b_command_can_perform_calculations_When_you_type_b_SET_b_part_of_the_help_display_contains_p_p_The_A_switch_specifies_that_the_string_to_the_right_of_the_equal_sign_is_a_numerical_expression_that_is_evaluated_The_expression_evaluator_is_pretty_simple_and_supports_the_following_operations_in_decreasing_order_of_precedence_p_pre_grouping_arithmetic_operators_arithmetic_operators_lt_lt_gt_gt_logical_shift_amp_bitwise_and_bitwise_exclusive_or_bitwise_or_assignment_amp_lt_lt_gt_gt_expression_separator_pre_If_you_use_any_of_the_logical_or_modulus_operators_you_will_need_to_enclose_the_expression_string_in_quotes_Any_non_numeric_strings_in_the_expression_are_treated_as_environment_variable_names_whose_values_are_converted_to_numbers_before_using_them_If_an_environment_variable_name_is_specified_but_is_not_defined_in_the_current_environment_then_a_value_of_zero_is_used_This_allows_you_to_do_arithmetic_with_environment_variable_values_without_having_to_type_all_those_signs_to_get_their_values_If_SET_A_is_executed_from_the_command_line_outside_of_a_command_script_then_it_displays_the_final_value_of_the_expression_The_assignment_operator_requires_an_environment_variable_name_to_the_left_of_the_assignment_operator_Numeric_values_are_decimal_numbers_unless_prefixed_by_0x_for_hexadecimal_numbers_and_0_for_octal_numbers_So_0x12_is_the_same_as_18_is_the_same_as_022_Please_note_that_the_octal_notation_can_be_confusing_08_and_09_are_not_valid_number_p_We_can_script_b_Yesterday_bat_b_to_calculate_yesterdays_date_returning_the_b_PDMM_b_b_PDDD_b_and_b_PDYY_b_environment_variables_p_p_code_echo_off_br_call_univdate_br_Force_non_leading_zero_as_it_may_cause_failure_br_set_a_PDDD_1_DD_101_br_set_a_PDMM_1_MM_100_br_set_a_PDYY_YY_br_if_PDDD_GTR_0_goto_return_br_set_a_PDMM_PDMM_1_br_if_PDMM_GTR_0_goto_isleap_br_set_a_PDDD_31_br_set_a_PDMM_12_br_set_a_PDYY_PDYY_1_br_goto_return_br_isleap_br_if_not_PDMM_EQU_2_goto_days_PDMM_br_Temporarily_use_PDDD_as_a_work_field_br_set_a_PDDD_PDYY_4_br_set_a_PDDD_PDDD_4_br_if_PDDD_EQU_PDYY_goto_leap_br_set_a_PDDD_28_br_goto_return_br_leap_br_set_a_PDDD_29_br_goto_return_br_days1_br_days3_br_days5_br_days7_br_days8_br_days10_br_set_a_PDDD_31_br_goto_return_br_days4_br_days6_br_days9_br_days11_br_set_a_PDDD_30_br_return_br_Force_leading_zero_when_day_or_month_is_single_digit_br_set_a_PDDD_PDDD_100_br_set_PDDD_PDDD_1_2_br_set_a_PDMM_PDMM_100_br_set_PDMM_PDMM_1_2_br_code_p_p_b_Note_b_To_calculate_that_the_year_was_divisible_by_4_a_leap_year_I_could_have_replaced_p_p_code_set_a_PDDD_PDYY_4_br_set_a_PDDD_PDDD_4_br_if_PDDD_EQU_PDYY_goto_leap_code_p_p_with_p_p_code_set_a_PDDD_PDYY_4_br_if_PDDD_EQU_0_goto_leap_code_begin_bookmark_heading_p_p_a_name_l_a_p_table_width_100_cellpadding_0_cellspacing_0_border_0_tr_td_font_face_arial_helvetica_size_2_class_head3_b_class_bold_How_do_I_test_manipulate_strings_b_font_td_td_align_right_valign_bottom_a_href_#top_target__self_img_src_http_www_microsoft_com_technet_images_arrowup_gif_width_9_height_9_border_0_alt_Back_to_Top_a_td_tr_tr_td_colspan_2_bgcolor_#FFCC00_img_src_http_www_microsoft_com_technet_images_spacer_gif_alt_width_1_height_1_border_0_td_tr_table_img_src_http_www_microsoft_com_technet_images_spacer_gif_alt_width_1_height_12_border_0_br_end_bookmark_heading_p_Answer_If_your_batch_script_needs_to_determine_if_a_string_is_a_sub_set_of_a_larger_string_the_easiest_method_is_to_use_environment_variable_string_substitution_p_p_b_set_work_string_substring_br_if_not_work_EQU_string_echo_string_contains_substring_b_p_p_If_the_b_substring_b_is_an_environment_variable_b_set_work_string_substring_b_or_b_set_work_string_substring_b_does_b_NOT_b_work_p_p_You_can_use_the_b_FOR_b_command_to_parse_this_expression_but_using_the_b_CALL_b_command_is_much_easier_p_p_b_call_set_work_string_substring_br_if_not_work_EQU_string_echo_string_contains_substring_b_p_p_To_determine_if_your_path_contains_a_specific_folder_b_call_chkpath_folder_b_p_p_Example_call_chkpath_c_program_files_support_tools_where_b_chkpath_bat_b_contains_p_p_code_echo_off_br_setlocal_br_set_chkpath_N_br_if_1_">\{\} goto :EOF<br>
  11. @echo.<br>
  13. @echo ^%%1=%1<br>
  15. @echo ^%%~f1=%~f1<br>
  17. @echo ^%%~d1=%~d1<br>
  19. @echo ^%%~p1=%~p1<br>
  21. @echo ^%%~n1=%~n1<br>
  23. @echo ^%%~x1=%~x1<br>
  25. @echo ^%%~s1=%~s1<br>
  27. @echo ^%%~dp1=%~dp1<br>
  29. @echo ^%%~nx1=%~nx1<br>
  31. ::Shift parameter string<br>
  33. shift<br>
  35. goto :loop<br></a></h1>

If I type:

  1. <b>demo "C:\Documents and Settings\Jerry\My Documents\My Pictures\Jerold.jpg" <br>
  2. %SystemRoot%\Notepad.exe "%userprofile%"</b><br>

demo.bat will display:

  1. Batch file: C:\Util\<br><br>
  3. %1="C:\Documents and Settings\Jerry\My Documents\My Pictures\Jerold.jpg"<br>
  5. %~f1=C:\Documents and Settings\Jerry\My Documents\My Pictures\Jerold.jpg<br>
  7. %~d1=C:<br>
  9. %~p1=\Documents and Settings\Jerry\My Documents\My Pictures\<br>
  11. %~n1=Jerold<br>
  13. %~x1=.jpg<br>
  15. %~s1=C:\DOCUME~1\Jerry\MYDOCU~1\MYPICT~1\Jerold.jpg<br>
  17. %~dp1=C:\Documents and Settings\Jerry\My Documents\My Pictures\<br>
  19. %~nx1=Jerold.jpg<br><br>
  21. %1=C:\WINNT\Notepad.exe<br>
  23. %~f1=C:\WINNT\notepad.exe<br>
  25. %~d1=C:<br>
  27. %~p1=\WINNT\<br>
  29. %~n1=notepad<br>
  31. %~x1=.exe<br>
  33. %~s1=C:\WINNT\notepad.exe<br>
  35. %~dp1=C:\WINNT\<br>
  37. %~nx1=notepad.exe<br><br>
  39. %1="C:\Documents and Settings\Jerry"<br>
  41. %~f1=C:\Documents and Settings\Jerry<br>
  43. %~d1=C:<br>
  45. %~p1=\Documents and Settings\<br>
  47. %~n1=Jerry<br>
  49. %~x1=<br>
  51. %~s1=C:\DOCUME~1\Jerry<br>
  53. %~dp1=C:\Documents and Settings\<br>
  55. %~nx1=Jerry<br>

How do I perform calculations? Back to Top

Answer: The SET command can perform calculations. When you type SET /?, part of the help display contains:

"The /A switch specifies that the string to the right of the equal sign is a numerical expression that is evaluated. The expression evaluator is pretty simple and supports the following operations, in decreasing order of precedence:

    ()                  - grouping                                  * / %               - arithmetic operators                                  + -                 - arithmetic operators                                  << >>               - logical shift                                  &                   - bitwise and                                  ^                   - bitwise exclusive or                                  |                   - bitwise or                                  = *= /= %= += -=    - assignment                                  &= ^= |= <<= >>=                                  ,                   - expression separator
If you use any of the logical or modulus operators, you will need to enclose the expression string in quotes. Any non-numeric strings in the expression are treated as environment variable names whose values are converted to numbers before using them. If an environment variable name is specified but is not defined in the current environment, then a value of zero is used. This allows you to do arithmetic with environment variable values without having to type all those % signs to get their values. If SET /A is executed from the command line outside of a command script, then it displays the final value of the expression. The assignment operator requires an environment variable name to the left of the assignment operator. Numeric values are decimal numbers, unless prefixed by 0x for hexadecimal numbers, and 0 for octal numbers. So 0x12 is the same as 18 is the same as 022. Please note that the octal notation can be confusing: 08 and 09 are not valid number

We can script Yesterday.bat to calculate yesterdays date, returning the PDMM, PDDD, and PDYY environment variables:

  1. @echo off<br>
  3. call univdate<br>
  5. ::Force non-leading zero, as it may cause failure<br>
  7. set /a PDDD=1%DD% - 101<br>
  9. set /a PDMM=1%MM% - 100<br>
  11. set /a PDYY=%YY%<br>
  13. if %PDDD% GTR 0 goto return<br>
  15. set /a PDMM=%PDMM% - 1<br>
  17. if %PDMM% GTR 0 goto isleap<br>
  19. set /a PDDD=31<br>
  21. set /a PDMM=12<br>
  23. set /a PDYY=%PDYY% - 1<br>
  25. goto return<br>
  27. :isleap<br>
  29. if not %PDMM% EQU 2 goto days%PDMM%<br>
  31. ::Temporarily use PDDD as a work field<br>
  33. set /a PDDD=%PDYY% / 4<br>
  35. set /a PDDD=%PDDD% * 4<br>
  37. if %PDDD% EQU %PDYY% goto leap<br>
  39. set /a PDDD=28<br>
  41. goto return<br>
  43. :leap<br>
  45. set /a PDDD=29<br>
  47. goto return<br>
  49. :days1<br>
  51. :days3<br>
  53. :days5<br>
  55. :days7<br>
  57. :days8<br>
  59. :days10<br>
  61. set /a PDDD=31<br>
  63. goto return<br>
  65. :days4<br>
  67. :days6<br>
  69. :days9<br>
  71. :days11<br>
  73. set /a PDDD=30<br>
  75. :return<br>
  77. ::Force leading zero when day or month is single digit<br>
  79. set /a PDDD=%PDDD% + 100<br>
  81. set PDDD=%PDDD:~1,2%<br>
  83. set /a PDMM=%PDMM% + 100<br>
  85. set PDMM=%PDMM:~1,2%<br>

Note To calculate that the year was divisible by 4, a leap year, I could have replaced:

  1. set /a PDDD=%PDYY% / 4<br>
  3. set /a PDDD=%PDDD% * 4<br>
  5. if %PDDD% EQU %PDYY% goto leap


  1. set /a PDDD= %PDYY% ^%% 4<br>
  3. if %PDDD% EQU 0 goto leap

How do I test / manipulate strings? Back to Top

Answer: If your batch script needs to determine if a string is a sub-set of a larger string, the easiest method is to use environment variable string substitution:

set work=%string:substring=%
if not "%work%" EQU "%string%" @echo %string% contains substring.

If the substring is an environment variable, set work=%string:%substring%=% or set work=%%string:%substring%=%% does NOT work.

You can use the FOR command to parse this expression, but using the CALL command is much easier:

call set work=%%string:%substring%=%%
if not "%work%" EQU "%string%" @echo %string% contains %substring%.

To determine if your path contains a specific folder, call chkpath "folder"

Example: call chkpath "c:\program files\support tools", where chkpath.bat contains:

  1. @echo off<br>
  3. setlocal<br>
  5. set $chkpath=N<br>
  7. if \{%1\}\{\} goto syntax<br>
  9. set fold=%1<br>
  11. :: Strip quotes<br>
  13. set folder=%fold:"=%<br>
  15. call set work=%%path:%folder%=%%<br>
  17. if "%work%" EQU "%path%" goto :end<br>
  19. set $chkpath=Y<br>
  21. goto :end<br>
  23. :syntax<br>
  25. @echo Syntax: ChkPath Folder<br>
  27. :end<br>
  29. endlocal&set $chkpath=%$chkpath%<br>

Note chkpath.bat sets the $chkpath environment variable to Y if the string is found.

If you need to determine the position and length of the "folder" string in the path, chkpath.bat should contain:

@echo off<br>                              setlocal<br>                              set /a $pos=0<br>                              set /a $len=0<br>                              set $chkpath=N<br>                              if \{%1\}==\{\} goto syntax<br>                              set fold=%1<br>                              :: Strip quotes<br>                              set folder=%fold:"=%<br>                              call set work=%%path:%folder%=%%<br>                              if "%work%" EQU "%path%" goto :end<br>                              set $chkpath=Y<br>                              set find=%folder%###<br>                              :lenloop<br>                              call set work=%%find:~%$len%,^3%%<br>                              if "%work%" EQU "###" goto fndpos<br>                              set /a $len=%$len% + 1<br>                              goto lenloop<br>                              :fndpos<br>                              call set work=%%path:~%$pos%^,%$len%%%<br>                              if /i "%work%" EQU "%folder%" goto :end<br>                              set /a $pos=%$pos% + 1<br>                              goto fndpos<br>                              :syntax<br>                              @echo Syntax: ChkPath Folder<br>                              :end<br>                              endlocal&amp;set $chkpath=%$chkpath%&amp;set /a $pos=%$pos%&amp;set /a $len=%$len%<br>

Note $pos starts at position 0.

Sample Usage

set look=c:\program files\support tools
call chkpath "%look%"
if "%$chkpath%" EQU "Y" @echo %look% is at position %$pos% for a length of %$len%

How do I read a file and process the lines of text? Back to Top

Answer: To process the contents of a text file, you can parse it with the FOR command:

for /f "Tokens=*" %%a in (filenName.Extension) do set line=%%a&call :parse


for /f "Tokens=*" %%a in ('type "filenName.Extension"') do set line=%%a&call :parse

Note See FOR /? for additional options.

Example: To display only those keys that have dword values, and their dword values, in a c:\folder\registry.reg file:

@echo off<br>                              setlocal<br>                              set key=<br>                              for /f "Tokens=*" %%a in ('type d:\zipnew\zz.reg') do set line=%%a&amp;call :parse<br>                              endlocal<br>                              goto :EOF<br>                              :parse<br>                              ::Strip command control codes<br>                              set work=%line:"=%<br>                              set work=%work::=%<br>                              set work=%work:(=%<br>                              set work=%work:)=%<br>                              set work=%work:^&amp;=%<br>                              set work=%work:^|=%<br>                              set work=%work:^&gt;=%<br>                              set work=%work:^&lt;=%<br>                              set work=%work:^%=%<br>                              set work=%work:^!=%<br>                              set work=%work:^;=%<br>                              ::Save the key<br>                              if \{%work:~0,1%\}==\{\[\} set key=%line%&amp;goto :EOF<br>                              set dw=%work:dword=%<br>                              if "%dw%" EQU "%work%" goto :EOF<br>                              @echo %key% - %line%<br>

How do I launch a process at a different priority? Back to Top

Answer: When you type start /?, you receive:

Starts a separate window to run a specified program or command.                              START \["title"\] \[/Dpath\] \[/I\] \[/MIN\] \[/MAX\] \[/SEPARATE | /SHARED\]                                     \[/LOW | /NORMAL | /HIGH | /REALTIME | /ABOVENORMAL | /BELOWNORMAL\]                                     \[/WAIT\] \[/B\] \[command/program\]
\[parameters\] "title" Title to display in window title bar. path Starting directory B Start application without creating a new window. The application has ^C handling ignored. Unless the application enables ^C processing, ^Break is the only way to interrupt the application I The new environment will be the original environment passed to the cmd.exe and not the current environment. MIN Start window minimized MAX Start window maximized SEPARATE Start 16-bit Windows program in separate memory space SHARED Start 16-bit Windows program in shared memory space LOW Start application in the IDLE priority class NORMAL Start application in the NORMAL priority class HIGH Start application in the HIGH priority class REALTIME Start application in the REALTIME priority class ABOVENORMAL Start application in the ABOVENORMAL priority class BELOWNORMAL Start application in the BELOWNORMAL priority class WAIT Start application and wait for it to terminate command/program If it is an internal cmd command or a batch file then the command processor is run with the /K switch to cmd.exe. This means that the window will remain after the command has been run. If it is not an internal cmd command or batch file then it is a program and will run as either a windowed application or a console application. parameters These are the parameters passed to the command/program If Command Extensions are enabled, external command invocation through the command line or the START command changes as follows: non-executable files may be invoked through their file association just by typing the name of the file as a command. (e.g. WORD.DOC would launch the application associated with the .DOC file extension). See the ASSOC and FTYPE commands for how to create these associations from within a command script. When executing an application that is a 32-bit GUI application, CMD.EXE does not wait for the application to terminate before returning to the command prompt. This new behavior does NOT occur if executing within a command script. When executing a command line whose first token is the string "CMD " without an extension or path qualifier, then "CMD" is replaced with the value of the COMSPEC variable. This prevents picking up CMD.EXE from the current directory. When executing a command line whose first token does NOT contain an extension, then CMD.EXE uses the value of the PATHEXT environment variable to determine which extensions to look for and in what order. The default value for the PATHEXT variable is: .COM;.EXE;.BAT;.CMD Notice the syntax is the same as the PATH variable, with semicolons separating the different elements. When searching for an executable, if there is no match on any extension, then looks to see if the name matches a directory name. If it does, the START command launches the Explorer on that path. If done from the command line, it is the equivalent to doing a CD /D to that path.

How do I display the current directory in the Title bar of a batch files command Windows? Back to Top

Answer: The start command can set the initial Title in a command Window.

To cause the batch file to display the current directory every time it changes, add the following commands after each current directory change:

for /f "Tokens=*" %%i in ('CD') do set CurDir=%%i<br>                              title %CurDir%<br>

How can a batch file alter the size of its' CMD Window? Back to Top

Answer: If you want to scroll the CMD window while a batch file is running, you can alter the Windows width (characters) and depth (screen buffer lines) by issuing a mode command in the batch file:

mode con\[:\] \[cols=c\] \[lines=n\]


<br><b>con\[:\]</b>   indicates the change is to be made to the current command prompt window.<br><br><b>cols=c</b>   specifies the width, <b>c</b>, in characters.<br><br><b>lines=n</b>  specifies the number of lines, <b>n,</b> in the screen buffer.<br>

Example: mode con: cols=100 lines=999

How can I get a batch file to prompt for user input? Back to Top

Answer: The SET command support the /P switch:

SET /P variable=\[promptString\]

"The /P switch allows you to set the value of a variable to a line of input
entered by the user. Displays the specified promptString before reading
the line of input. The promptString can be empty."

Example: To prompt for folders to DIR:

@echo off<br>                              setlocal<br>                              :loop<br>                              ::undefine the %folder% environment variable<br>                              set folder=<br>                              set /p folder=Type the folder path and press Enter. When finished, press Enter.<br>                              if \{%folder%\}==\{\} goto :end<br>                              @echo.<br>                              if not exist %folder% @echo %folder% does NOT exist.&amp;goto :loop<br>                              dir %folder%<br>                              @echo.<br>                              goto loop<br>                              :end<br>                              endlocal<br>

How can I get a batch file to 'sleep' for n seconds? Back to Top

Answer: The Windows 2000 Resource Kits provide sleep.exe to allow a batch file to sleep for n seconds.

You can emulate this behavior by using the PING (Packet InterNet Groper) command:

ping -n seconds+1>nul

To sleep for 15 seconds, type:

ping -n 16>nul

How can I get a batch file to beep for attention? Back to Top

Answer: To cause a batch file to beep for attention, you need to send a BEL character.

To create a Bell.bat in your path:

At a CMD prompt, switch (CD) to a folder in your path.


edit bell.bat                              @echo<space><CTRL+P><CTRL+G><ENTER>                              <ALT+S>           (Saves bell.bat)                              <ALT+X>           (Exits edit)
Note <> indicates that you type the key(s) within the <>.

When you need to beep for attention:

call bell

How do I pipe batch output, including commands and responses, to a log file? Back to Top

Answer: The general syntax for piping batch output, including commands and responses, to a log file is:

Drive:\BatFolder\BatchName.bat>Drive:\LogFolder\LogName.log 2>&1

What is delayed environment variable expansion? Back to Top

The default behavior of the CMD command processor is to evaluate an environment variable once per statement execution.

To demonstrate this behavior, assume that your c:\test folder has 3 files:


If you run a batch script containing:

@echo off<br>                              cd /d c:\test<br>                              @echo on<br>                              set LIST=<br>                              for %%i in (*) do set LIST=%LIST% %%i<br>                              echo %LIST%<br>

You would see the following:

C:\TEST\&gt;set LIST=<br>                              C:\TEST\&gt;for %i in (*) do set LIST= %i<br>                              C:\TEST\&gt;set LIST= File1.txt<br>                              C:\TEST\&gt;set LIST= File2.txt<br>                              C:\TEST\&gt;set LIST= File3.txt<br>                              C:\TEST\&gt;echo  File3.txt<br>                              C:\TEST\&gt; File3.txt

You can see from this example that the LIST variable is expanded just once when the FOR statement is executed. Since LIST was empty, only the last file found is set into the variable.

Windows 2000 supports delayed environment variable expansion. You must enable delayed environment variable expansion for the CMD session by using the CMD /V:ON switch, or by issuing a setlocal ENABLEDELAYEDEXPANSION command.

With delayed environment variable expansion enabled, you can use the ! instead of the %, as follows:

@echo off<br>                              cd /d c:\test<br>                              @echo on<br>                              set LIST=<br>                              for %%i in (*) do set LIST=!LIST! %%i<br>                              echo %LIST%<br>

This yields the following output:

C:\TEST\&gt;set LIST=<br>                              C:\TEST\&gt;for %i in (*) do set LIST=!LIST! %i<br>                              C:\TEST\&gt;set LIST=!LIST! File1.txt<br>                              C:\TEST\&gt;set LIST=!LIST! File2.txt<br>                              C:\TEST\&gt;set LIST=!LIST! File3.txt<br>                              C:\TEST\&gt;echo  File1.txt File2.txt File3.txt<br>                              C:\TEST\&gt; File1.txt File2.txt File3.txt

You can have delayed environment variable expansion enabled by default, if you use Regedt32 to navigate to either of the following keys:

<b>HKEY_LOCAL_MACHINE \Software \Microsoft \Command Processor</b><br><br><b>HKEY_CURRENT_USER \Software \Microsoft \Command Processor</b><br>

On the Edit menu, Add Value name DelayedExpansion, as a REG_DWORD data type. A data value of 1 enables delayed environment variable expansion and a data value of 0 disables it. Invoking the /V:ON or /V:OFF switch on CMD.EXE and/or using the setlocal ENABLEDELAYEDEXPANSION command, overrides the registry setting for the CMD session.

What are the conditional processing symbols? Back to Top

Answer: From the ntcmds.chm file:

Conditional processing symbols give you control over the execution of commands.  <br>                              Processing Commands Conditionally  You use conditional processing symbols to issue <br>                              multiple commands from the same prompt and to act based on the results of a command.<br>                              The ampersand (&amp;) separates multiple commands on one command line. <br>                              The parentheses groups multiple commands. <br>                              The semicolon or comma (; ,) separate command parameters. <br>                              The caret (^) cancels a subsequent command symbol's special meaning so you can use a <br>                              command symbol as text. <br>                              The double ampersand (&amp;&amp;) causes the command following this symbol to run only if the <br>                              command preceding the symbol is successful. <br>                              The double pipe (||) causes the command following this symbol to run only if the command <br>                              preceding the symbol fails.<br>


dir filename.txt>nul && type filename.txt is equivalent to if exist filename.txt type filename.txt

dir filename.txt>nul || @echo.>filename.txt is equivalent to if not exist filename.txt @echo.>filename.txt

How do I send a pop-up message? Back to Top

Answer: The syntax of the net send command is:

net send \{name | * | /domain\[:name\] | /users\} message

To send a pop-up to all users in your domain, type:

net send /domain This is a message.

Note Windows NT-based client run the Messenger service by default. Other Windows clients must be running Winpopup.exe to receive the message.

net send jennifer hello will send hello to Jennifer, if she is logged on.

net send /users hello will send hello to all users that are connected to your computer.

To send a files contents to logged on members of one or more domain groups, use:

call sendfilegroup filename.txt group1 \[group2 group3 ... groupn\], where sendfilegroup.bat contains:

@echo off<br>                              setlocal ENABLEDELAYEDEXPANSION<br>                              if \{%2\}==\{\} (echo usage: sndflegrp msgfile group-list) &amp; (goto :EOF)<br>                              if not exist %1 (echo usage: sndflegrp msgfile group-list) &amp; (goto :EOF)<br>                              set msg=<br>                              for /f "Tokens=*" %%m in ('type %1') do set msg=!msg! %%m<br>                              :LOOP<br>                              if \{%2\}==\{\} endlocal&amp;goto :EOF<br>                              for /f "Skip=8 Tokens=*" %%i in ('net group %2 /domain') do call :msg "%%i"<br>                              shift /2<br>                              goto :LOOP<br>                              :msg<br>                              If %1=="The command completed successfully." goto :EOF<br>                              set users=%1<br>                              set user=%users:~1,20%##<br>                              call :sndmsg&gt;nul 2&gt;&amp;1<br>                              if "%user%"=="" goto end<br>                              set user=%users:~26,20%##<br>                              call :sndmsg&gt;nul 2&gt;&amp;1<br>                              if "%user%"=="" goto end<br>                              set user=%users:~51,20%##<br>                              call :sndmsg&gt;nul 2&gt;&amp;1<br>                              goto :EOF<br>                              :sndmsg<br>                              set user=%user:  =%<br>                              set user=%user: ##=##%<br>                              set user=%user:##=%<br>                              set user=%user:"=%<br>                              if "%user%"=="" goto :EOF<br>                              set comp=%user%<br>                              set comp=%comp:$=%<br>                              if "%comp%"=="%user%" net send "%user%" %msg%<br>

How do I execute a command in every sub-folder? Back to Top

Answer: The FOR /R command is meant to traverse sub-folders.

The general syntax is:

FOR /R \[\[drive:\]path\] %variable IN (set) DO command \[command-parameters\]

Walks the directory tree rooted at \[drive:\]path, executing the FOR
statement in each directory of the tree. If no directory
specification is specified after /R then the current directory is
assumed. If set is just a single period (.) character then it
will just enumerate the directory tree.