2

I am trying to set the environment variable in my powershell script.

Heres my code snippet.It sets the system environment variable (System Properties > Environment variable > Path) however, I am unable to start rabbitmq-service in powershell.

'$ENV:PATH' command output doesn't have the newly added path. After system restart $ENV:PATH contains the new path but the command 'rabbitmq-service' still doesnt work.

  # SET Erlang and RabbitMQ  Home Path
    $ERLANG_HOME = "$env:PROGRAMFILES\erl9.2"
    [System.Environment]::SetEnvironmentVariable("ERLANG_HOME", $ERLANG_HOME, "Machine")

    $ERTS_HOME = "$env:PROGRAMFILES\erts-9.2"
    [System.Environment]::SetEnvironmentVariable("ERTS_HOME", $ERTS_HOME, "Machine")

    $RABBITMQ_HOME = "$env:PROGRAMFILES\RabbitMQ Server\rabbitmq_server-3.6.11" 
    [System.Environment]::SetEnvironmentVariable("RABBITMQ_HOME", $RABBITMQ_HOME, "Machine")


    # Add Erlang and RabbitMQ to Path     
    $System_Path_Elems = [System.Environment]::GetEnvironmentVariable("PATH", "Machine").Split(";")
    if (!$System_Path_Elems.Contains("$RABBITMQ_HOME\sbin") -and !$System_Path_Elems.Contains("$ERLANG_HOME\bin") -and !$System_Path_Elems.Contains("$ERTS_HOME\bin"))
    {       
    $newPath = [System.String]::Join(";", $System_Path_Elems + "$ERLANG_HOME\bin" + "$ERTS_HOME\bin" + "$RABBITMQ_HOME\sbin")
    [System.Environment]::SetEnvironmentVariable("PATH", $newPath, "Machine")   
    }

If I set the PATH using $env:PATH as below in my script, It works.

$env:Path += ";C:\\Program Files\\erl9.2\\erts-9.2\\bin;
C:\\Program Files\\RabbitMQ Server\\rabbitmq_server-3.6.11\\sbin;C:\\Program Files\\erl9.2\\bin"  

I am able to execute the following commands without any issues.

rabbitmq-service remove
rabbitmq-plugins enable rabbitmq_management --offline
rabbitmq-service install
rabbitmq-service start

So, why 'SetEnvironmentVariable' doesn't work. Am I missing something here?

nad87563
  • 3,672
  • 7
  • 32
  • 54
  • 1
    the method you are calling changes the top level environment ... but it _does not change the current PoSh environment_. [*grin*] the change you made with that method will be available in the next PoSh session you start. – Lee_Dailey Oct 03 '19 at 00:47
  • Can you provide us with the output of your $env:PATH after you run the script? – Peter Kay Oct 03 '19 at 01:07

1 Answers1

4
$env:PATH = ...

is equivalent to (namespace prefix System. implied):

[Environment]::SetEnvironmentVariable(
  'PATH', 
   ..., 
   [EnvironmentVariableTarget]::Process
)

PowerShell automatically converts strings to enumeration values, so 'Process' in lieu of [EnvironmentVariableTarget]::Process works too.

That is, in both cases you're updating the environment variable for the current process only - future sessions will not see the updated value.

By contrast, if you use [Environment]::SetEnvironmentVariable() with the [EnvironmentVariableTarget]::Machine / [EnvironmentVariableTarget]::User targets, you update the persistent definitions machine-wide / for the current user only, without also updating the value in the current process; that is, these definitions only take effect in future sessions.

Unfortunately, there is no single call that would allow you to do both, so you'll need two calls:

# Update the current process' env.var
$env.PATH = ... 
# Also persist the new value.
# Note that targeting [EnvironmentVariableTarget]::Machine requires
# ELEVATION (running as admin).
[Environment]::SetEnvironmentVariable('PATH', $env:PATH, <target>)

Caveat:

  • On Windows, the process-level $env:PATH value is a composite value, the concatenation of the registry-based machine-level and the user-level definitions.

  • Additionally, just as $env:PATH only contains expanded, literal values - even though he underlying registry entries may be defined by incorporating references to other environment variables (e.g. %SystemRoot%) - [Environment]::SetEnvironmentVariable() only supports writing literal paths.

A proper solution therefore requires reading and writing raw (unresolved) definitions from the registry, as shown in this answer.

mklement0
  • 382,024
  • 64
  • 607
  • 775