NT's and OS/2's

SETLOCAL and ENDLOCAL

The syntax given below is for Windows NT 4.
In OS/2 (CMD.EXE) SETLOCAL and ENDLOCAL follow the same basic syntax, without the extensions of NT's Command Extensions.

Note:

The parts of this text that are displayed in magenta are valid for Windows 2000 and later versions only

SETLOCAL

Begins localization of environment changes in a batch file.
Environment changes made after SETLOCAL has been issued are local to the batch file.ENDLOCAL must be issued to restore the previous settings.

SETLOCAL

In Windows NT 4 and later versions, if Command Extensions are enabled, SETLOCAL changes as follows:

SETLOCAL batch command now accepts an optional argument, which can be either ENABLEEXTENSIONS or DISABLEEXTENSIONS.
This will enable or disable the Command process extensions until the matching ENDLOCAL command, regardless of their setting prior to the SETLOCAL command.

The SETLOCAL command will set the ERRORLEVEL value if given an argument.
It will be zero if one of the two valid arguments is given and one otherwise.
You can use this in batch scripts to determine if the extensions are available, using the following technique:

This works because on old versions of CMD.EXE, SETLOCAL does not set the ERRORLEVEL value.
The VERIFY command with a bad argument initializes the ERRORLEVEL value to a non-zero value.

ENDLOCAL

Ends localization of environment changes in a batch file.
Environment changes made after ENDLOCAL has been issued are not local to the batch file; the previous settings are not restored on termination of the batch file.

If the corresponding SETLOCAL enabled or disabled command extensions using the new ENABLEEXTENSIONS or DISABLEEXTENSIONS options, then after the ENDLOCAL, the enabled/disabled state of command extensions will be restored to what it was prior to the matching SETLOCAL command execution.

Bypass SETLOCAL/ENDLOCAL

Sometimes it would be nice if we could use SETLOCAL and ENDLOCAL to preserve the initial environment but still change one variable "permanently", in the SORTDATE and SORTTIME examples, for example.

I recently saw a posting at the alt.msdos.batch.nt newsgroup where Phil Robyn solved this problem in an ingenious way:

SET TEST=
SETLOCAL
:: Variable test is set within local environment, which means
:: its changes are flushed by the next ENDLOCAL command
SET TEST=Some new value
:: By using the ampersand and the following SET command on the
:: same line as the ENDLOCAL command, %TEST% is resolved before
:: the ENDLOCAL command "restores" its value
ENDLOCAL & SET TEST=%TEST%
SET TEST

This way the environment variable TEST and its value are preserved in spite of the ENDLOCAL command.
See my Conditional Execution page for an explanation of the ampersand's usage.

By default command extensions are enabled.
However, to be absolutely sure that they are, either use SETLOCAL ENABLEEXTENSIONS within your NT shell scripts (batch files) or execute those scripts using CMD /X.

Likewise, you may disable command extensions using SETLOCAL DISABLEEXTENSIONS or CMD /Y.

Read my SETLOCAL page if you intend to use SETLOCAL extension switches.