Search code examples
javawindowspowershellenvironment-variablesjava-home

%JAVA_HOME%\bin not expanding string after PowerShell sets PATH


I'm creating a PowerShell script to assist me in setting up the newest version of Java and JavaFX on Windows. Procedure is as follows:

  1. Determine newest version of Java and JavaFX from jkd.java.net and gluonhq.com
  2. Download archives from online sources, respectively
  3. Extract the archives to specified location on system
  4. Delete archives
  5. Update User Environment Variables with JAVA_HOME and PATH_TO_FX
  6. Append User Environment Variable PATH with %JAVA_HOME%\bin

Steps 1-5 all work as expected, step 6 however is causing some headaches. The code for step 6 as seen at the very end of the script is the following:

$p = [Environment]::GetEnvironmentVariable("PATH", [EnvironmentVariableTarget]::User)
$p = $p.Split(";", [System.StringSplitOptions]::RemoveEmptyEntries)
$p += "%JAVA_HOME%\bin"
$p = ($p -join ";") + ";"
<# [Environment]::SetEnvironmentVariable("PATH", $p, [EnvironmentVariableTarget]::User) #>
<# Set-ItemProperty HKCU:\Environment -Name "PATH" -Value $p -Type ExpandString #>
setx PATH "$p"

Originally I used the first commented code SetEnvironmentVariable. With research I determined that this sets the Registry value to a type of REG_SZ (the default). That doesn't work because it requires a type of REG_EXPAND_SZ for anything that uses %% substitutions. The second commented code Set-ItemProperty does provide the appropriate type, but when I did a (dir env:PATH).Value (after launching a new PowerShell instance to ensure I had the appropriate environment) the PATH does not show the appended/expanded %JAVA_HOME%\bin at all. However, checking the registry and using the Control Panel > System Properties I can see %JAVA_HOME%\bin displayed on both. So what gives?

The code only worked when I used the setx command. I don't have a problem with it working this way, but isn't there a more PowerShell "best practices" way of achieving the same result? I found this question which seems to have done precisely what I did and it seemingly worked. Is it an order of operations problem (as they use Set-ItemProperty and then SetEnvironmentVariable)?


Solution

  • Nevermind, the code works using Set-ItemProperty. Exiting PowerShell and starting a new PowerShell instance does not cause a reload of the environment as hinted at by @Eryk Sun's comment. It is necessary to either completely sign out the user (forcing a sign in) or reboot the computer in order for %JAVA_HOME% to be expanded.