Environment Variables
There are several ways to read or write environment variables:
- Use the WSH Shell object
- Use WMI's Win32_Environment class
- Read/write the variables directly from/to the registry
As directly accessing the registry is both risky and usually requires a reboot for the changes to take effect, I would not recommend using it, unless all other methods fail.
WSH Shell Object
Read Environment Variables
Reading an environment variable is simple:
Set wshShell = CreateObject( "WScript.Shell" )
WScript.Echo wshShell.ExpandEnvironmentStrings( "%PATHEXT%" )
wshShell = Nothing
The output will look like this:
.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH
The ExpandEnvironmentStrings
method can expand environment variables embedded in a string too:
Set wshShell = CreateObject( "WScript.Shell" )
WScript.Echo wshShell.ExpandEnvironmentStrings( "PATH=%PATH%" )
wshShell = Nothing
The output will look like this (but probably longer):
PATH=C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem
This behaviour is exactly like that of a batch file: the environment variable is replaced by its value when the string is processed.
Some environment variables are actually the result of two variables being merged. The environment variable PATH
, for example, is defined in the system environment as well as in the user environment, as can be seen in this screenshot of the "System" Control Panel applet.
In this case, if we query the PATH
environment variable like we did just before, the result will look like this:
PATH=C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;D:\Test
As we can see, the PATH value from the user environment was appended to the value from the system environment.
Other user variables, like TEMP
, overwrite their system counterpart:
Set wshShell = CreateObject( "WScript.Shell" )
WScript.Echo wshShell.ExpandEnvironmentStrings( "TEMP=%TEMP%" )
wshShell = Nothing
The output will look like this:
TEMP=C:\DOCUME~1\You\LOCALS~1\Temp
Note: | In fact, it gets even more complicated: if you look in the "System" Control Panel applet, you'll notice that the TEMP value in the user environment displays the long path name, not the short 8.3 notation. |
Only the system environment values will be available to other users logging on to the same computer, the user environment values are part of the (roaming) profile and hence will be different or even absent for other users.
As you may already have guessed, this technique is not suited for setting environment variables.
To set an environment variable, we first need to find a way to specify in which environment we would like to set that variable.
That is where we use the WSH Shell's Environment
method:
Set wshShell = CreateObject( "WScript.Shell" )
Set wshSystemEnv = wshShell.Environment( "SYSTEM" )
WScript.Echo "SYSTEM: TEMP=" & wshSystemEnv( "TEMP" )
Set wshSystemEnv = Nothing
Set wshShell = Nothing
Valid parameters for Environment
are PROCESS
, SYSTEM
, USER
and VOLATILE
.
The resulting output will look like this:
SYSTEM: TEMP=%SystemRoot%\TEMP
Had we used the PROCESS
parameter, the output would have looked like this:
PROCESS: TEMP=C:\DOCUME~1\Rob\LOCALS~1\Temp
This is the value the WSH Shell's ExpandEnvironmentStrings
method would return; ExpandEnvironmentStrings
can only read the process environment.
OK, time for a demonstration:
Set wshShell = CreateObject( "WScript.Shell" )
WScript.Echo Left( "Expanded" & Space( 12 ), 12 ) & wshShell.ExpandEnvironmentStrings( "TEMP=%TEMP%" )
arrEnvironments = Array( "PROCESS", "SYSTEM", "USER", "VOLATILE" )
For Each strEnv In arrEnvironments
Set wshEnv = wshShell.Environment( strEnv )
WScript.Echo Left( strEnv & Space( 12 ), 12 ) & "TEMP=" & wshEnv( "TEMP" )
Next
Set wshEnv = Nothing
Set wshShell = Nothing
This is what the resulting output will look like:
Expanded TEMP=C:\DOCUME~1\You\LOCALS~1\Temp
PROCESS TEMP=C:\DOCUME~1\You\LOCALS~1\Temp
SYSTEM TEMP=%SystemRoot%\TEMP
USER TEMP=%USERPROFILE%\Local Settings\Temp
VOLATILE TEMP=
Experiment, play with the code.
So far all we did is read environment variables, which is absolutely harmless.
Set Environment Variables
After having read the chapter on reading environment variables, setting them is only a small step.
We will use the WSH Shell's Environment
method again:
Set wshShell = CreateObject( "WScript.Shell" )
Set wshSystemEnv = wshShell.Environment( "SYSTEM" )
' Display the current value
WScript.Echo "TestSystem=" & wshSystemEnv( "TestSystem" )
' Set the environment variable
wshSystemEnv( "TestSystem" ) = "Test System"
' Display the result
WScript.Echo "TestSystem=" & wshSystemEnv( "TestSystem" )
' Delete the environment variable
wshSystemEnv.Remove( "TestSystem" )
' Display the result once more
WScript.Echo "TestSystem=" & wshSystemEnv( "TestSystem" )
Set wshSystemEnv = Nothing
Set wshShell = Nothing
The output should look like this:
TestSystem=
TestSystem=Test System
TestSystem=
List Environment Variables
To list all variables in the user environment:
Set wshShell = CreateObject( "WScript.Shell" )
Set wshUserEnv = wshShell.Environment( "USER" )
For Each strItem In wshUserEnv
WScript.Echo strItem
Next
Set wshUserEnv = Nothing
Set wshShell = Nothing
The result will look like this:
TEMP=%USERPROFILE%\Local Settings\Temp
TMP=%USERPROFILE%\Local Settings\Temp
If you read the previous chapters you will know how to list the variables from the other environments too.
WMI's Win32_Environment Class
Besides being able to access environment variables on remote computers, WMI's Win32_Environment class also allows us to access (read and set) environment variables for other users!
See
MSDN for detailed information on this class' properties.
Read or List Environment Variables
The following code, created with the help of
Scriptomatic, lists all TEMP variables on the local computer:
Set objWMIService = GetObject( "winmgmts://./root/CIMV2" )
strQuery = "SELECT * FROM Win32_Environment WHERE Name='TEMP'"
Set colItems = objWMIService.ExecQuery( strQuery, "WQL", 48 )
For Each objItem In colItems
WScript.Echo "Caption : " & objItem.Caption
WScript.Echo "Description : " & objItem.Description
WScript.Echo "Name : " & objItem.Name
WScript.Echo "Status : " & objItem.Status
WScript.Echo "SystemVariable : " & objItem.SystemVariable
WScript.Echo "UserName : " & objItem.UserName
WScript.Echo "VariableValue : " & objItem.VariableValue
WScript.Echo
Next
Set colItems = Nothing
Set objWMIService = Nothing
Set Environment Variables
To set a variable, specify new values for its Name
, UserName
and/or VariableValue
properties.
The following code, from the book
Windows Server Cookbook by Robbie Allen, creates a new system environment variable called FOOBAR:
strVarName = "FOOBAR"
strVarValue = "Foobar Value"
Set objVarClass = GetObject( "winmgmts://./root/cimv2:Win32_Environment" )
Set objVar = objVarClass.SpawnInstance_
objVar.Name = strVarName
objVar.VariableValue = strVarValue
objVar.UserName = "<SYSTEM>"
objVar.Put_
WScript.Echo "Created environment variable " & strVarName
Set objVar = Nothing
Set objVarClass = Nothing
And the following code removes the environment variable again by giving it an empty value:
strVarName = "FOOBAR"
Set objVarClass = GetObject( "winmgmts://./root/cimv2:Win32_Environment" )
Set objVar = objVarClass.SpawnInstance_
objVar.Name = strVarName
objVar.VariableValue = ""
objVar.UserName = "<SYSTEM>"
objVar.Put_
WScript.Echo "Removed environment variable " & strVarName
Set objVar = Nothing
Set objVarClass = Nothing
Replace the dot in the GetObject
commands by a remote computer name to manage environment variables on that remote computer.