Thursday, February 14, 2008

Set And Setx

Everybody knows to use set to set environment variable values.  And I guess everybody should know setx.  The crucial differences between set and setx are:

  • set takes effect in local cmd context.  Meaning once you exit or close the cmd window, you lose the environment variable.
  • setx takes effect in future cmd context.  So you won't see the environment variable and its value in the current cmd.  You need to open a new cmd window to see it.

This really leads to one obvious conclusion: always use set and setx side by side if you want to set something globally but you want to see it in effect immediately.

A good example is if you want to set an environment variable containing your current IP address.  You would do something like this:

ipconfig | findstr IPv4 > %TEMP%\ipaddress.out

REM This will give you something like this

REM IPv4 Address. . . . . . . . . . . : 192.168.1.3

REM You then parse the output file, taking the second token after splitting at the ":"

for /F "delims=: tokens=2" %i in (%TEMP%\ipaddress.out) do (

    set IPADDR=%i

)

REM Then remove the spaces

set IPADDR=%IPADDR: =%

REM Then to persist this in the system environment, you call setx.

setx /M IPADDR %IPADDR%

Now of course setx is much more powerful than simply calling it the way I did in the above example.  Take a look at setx /? to see the complete options.  For example the above usage can also be done using setx alone.

ipconfig | findstr IPv4 > %TEMP%\ipaddress.out

REM Then you use setx to read its value from a file, keying in on a string,

REM and get the value relative to that string. In this case we key in on the ":"

REM and get the token after that.  And setx coordinates start at 0, not 1.

setx /M IPADDR /F %TEMP%\ipaddress.out /R 0,1 ":"

The reason I hardly ever use this is because most of the time I need the environment variable defined in the current context first, and then also persisting it for future cmd contexts.   The second example above only does it for future context.

3 comments:

Rui Natário said...

Hey,

Maybe you can help me. I want to create a logon script to enforce to all users that all variables %tmp% and %temp%, both system and to all users, are set to a specific folder e.g. c:\trash. The purpose of this will be to also use a script to remove all the temp files at each machine shutdown or logoff. Everything is fine except the part where I cannot use setx in a logon script for the regular users because I get an error message stating the the user is not allowed to write to the registry. So, the users will keep on having their variables set to C:\documents and setting\....

Did I make myself clear?

Any ideas?

Thank you

Toby said...

I am trying to use setx remotely to update the PATH variable, eg.

setx /s MACHINE PATH "C:\oracle\instantclient_11_1;%PATH%" /m

The command returns without error, and when I look at the remote machine, the PATH has been updated, but instead of taking %PATH% from the remote machine, its taking it from the local machine where I am issuing the setx command.

Any ideas?

Thanks
Toby

Arif Sukoco said...

@Rui
I don't know the answer to your problem.

@Toby
The easiest thing I can think of is to get the remote machine's path using psexec (which you can find here

Another way to lookup remote path is by using the "reg" command. Do "req query" for the path on the remote machine.