169

I have to set environment variables on different windows machines, but I don't want to be bothered changing them manually by getting on the properties screen of "My Computer"

I want to do it from the command line, with a batch file. As far as I understand, using set will only change the variable for the processes I will call in the command window.

I want to set it definitely, so later, when running a new process, it will use those new settings I have set. Is there a way to do that from the command line?

Wai Ha Lee
  • 8,598
  • 83
  • 57
  • 92
0x26res
  • 11,925
  • 11
  • 54
  • 108
  • Whats the point of setting them from the command line if they are going permanent? You wont need to do it again. – d-live May 05 '11 at 13:10
  • 19
    Yes, but I have to do it on several computers, so running the script will save me some time. – 0x26res May 05 '11 at 13:19
  • 2
    Ok, in that case you can set your env on one computer and do an export of the entries described below and have a .reg file, if SETX isnt available to you. – d-live May 05 '11 at 13:23
  • That's what I've done. Thanks. – 0x26res May 05 '11 at 13:32
  • 2
    RE: 'Whats the point of setting them from the command line...' Where I work there is a constant requirement to a number of persistent environmental variables to different values in order to test/develop different versions of the software. Licensing means it can't be done any other way (e.g. running a VM) so our only resort is to use SETX in a batch script. Using .reg is less good as its harder to document/see exactly what's going on – Tony Eastwood Jan 14 '14 at 12:32

5 Answers5

250

Use the SETX command (note the 'x' suffix) to set variables that persist after the cmd window has been closed.

For example, to set an env var "foo" with value of "bar":

setx foo bar /m

Though it's worth reading the 'notes' that are displayed if you print the usage (setx /?), in particular:

  1. On a local system, variables created or modified by this tool will be available in future command windows but not in the current CMD.exe command window.

  2. On a remote system, variables created or modified by this tool will be available at the next logon session.

In PowerShell, the [Environment]::SetEnvironmentVariable command.

charlie arehart
  • 6,590
  • 3
  • 27
  • 25
Vik David
  • 3,640
  • 4
  • 21
  • 29
24

The MSDN documentation for environment variables tells you what to do:

To programmatically add or modify system environment variables, add them to the HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment registry key, then broadcast a WM_SETTINGCHANGE message with lParam set to the string "Environment". This allows applications, such as the shell, to pick up your updates.

You will of course need admin rights to do this. I know of no way to broadcast a windows message from Windows batch so you'll need to write a small program to do this.

eel ghEEz
  • 1,186
  • 11
  • 24
David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • 1
    Ok, so considering your solution, I have created a registry (.reg) file containing the environment variables I want to add/change. I'll then run this file on all the target PCs. I don't really need to send a windows message, as I will just restart the application that will be impacted. Thanks. – 0x26res May 05 '11 at 13:31
  • 1
    I'm adding your other answer here, as it was exactly what I was looking for when I stumbled upon this question: http://stackoverflow.com/a/19705691/3543437 – kayleeFrye_onDeck Jan 30 '15 at 22:49
  • 1
    @David, So why not `setx` per below? – Pacerier Jul 29 '17 at 07:28
  • I think this reg has the advantage of not truncating and not being powershell – eri0o Jun 16 '20 at 10:49
6
:: Sets environment variables for both the current `cmd` window 
::   and/or other applications going forward.
:: I call this file keyz.cmd to be able to just type `keyz` at the prompt 
::   after changes because the word `keys` is already taken in Windows.

@echo off

:: set for the current window
set APCA_API_KEY_ID=key_id
set APCA_API_SECRET_KEY=secret_key
set APCA_API_BASE_URL=https://paper-api.alpaca.markets

:: setx also for other windows and processes going forward
setx APCA_API_KEY_ID     %APCA_API_KEY_ID%
setx APCA_API_SECRET_KEY %APCA_API_SECRET_KEY%
setx APCA_API_BASE_URL   %APCA_API_BASE_URL%

:: Displaying what was just set.
set apca

:: Or for copy/paste manually ...
:: setx APCA_API_KEY_ID     'key_id'
:: setx APCA_API_SECRET_KEY 'secret_key'
:: setx APCA_API_BASE_URL   'https://paper-api.alpaca.markets'
gseattle
  • 986
  • 1
  • 14
  • 23
  • This so vastly simplified my algorithm work efficiency and saved so much time I thought I'd share it case it might help someone (of those capable of comprehending it) – gseattle Nov 13 '20 at 01:21
2

Indeed SET TEST_VARIABLE=value works for current process only, so SETX is required. A quick example for permanently storing an environment variable at user level.

  1. In cmd, SETX TEST_VARIABLE etc. Not applied yet (echo %TEST_VARIABLE% shows %TEST_VARIABLE%,
  2. Quick check: open cmd, echo %TEST_VARIABLE% shows etc.
  3. GUI check: System Properties -> Advanced -> Environment variables -> User variables for -> you should see Varible TEST_VARIABLE with value etc.
Alexei - check Codidact
  • 22,016
  • 16
  • 145
  • 164
1

An example with VBScript (.vbs)

Sub sety(wsh, action, typey, vary, value)
  Dim wu
  Set wu = wsh.Environment(typey)
  wui = wu.Item(vary)
  Select Case action
    Case "ls"
      WScript.Echo wui
    Case "del"
      On Error Resume Next
      wu.remove(vary)
      On Error Goto 0
    Case "set"
      wu.Item(vary) = value
    Case "add"
      If wui = "" Then
        wu.Item(vary) = value
      ElseIf InStr(UCase(";" & wui & ";"), UCase(";" & value & ";")) = 0 Then
        wu.Item(vary) = value & ";" & wui
      End If
    Case Else
      WScript.Echo "Bad action"
  End Select
End Sub

Dim wsh, args
Set wsh = WScript.CreateObject("WScript.Shell")
Set args = WScript.Arguments
Select Case WScript.Arguments.Length
  Case 3
    value = ""
  Case 4
    value = args(3)
  Case Else
    WScript.Echo "Arguments - 0: ls,del,set,add; 1: user,system, 2: variable; 3: value"
    value = "```"
End Select
If Not value = "```" Then
  ' 0: ls,del,set,add; 1: user,system, 2: variable; 3: value
  sety wsh, args(0), args(1), UCase(args(2)), value
End If
Rene
  • 976
  • 1
  • 13
  • 25
  • 24
    You should consider adding some context or an explanation to accompany your code. – adamdunson Sep 30 '13 at 03:25
  • 1
    Powerful piece of code +1. Works on XP without `setx` (and without possibility to install it). Simple use (in my case): `wsh.Environment("user").Item("myVar") = "my value"` – Marek Sep 30 '13 at 09:42
  • 2
    Since no one has taken the trouble, to use on XP (no Resource Kit or setx required), to accomplish {set foo=bar} for all (other) DOS windows: 1. save above code as SetVar.vbs 2. setvar.vbs set system foo "bar" Note, the *current* DOS window does not get FOO from this. Issue set foo=bar to achieve that – MicrosoftShouldBeKickedInNuts Nov 03 '17 at 04:33
  • 2
    Note also, this survives reboot (when you use the system parm) – MicrosoftShouldBeKickedInNuts Nov 03 '17 at 05:06