Today I played a bit with containers on Windows Server 2016, there is a quick start page on microsoft.com about how to install Docker with step by step instructions. One step involves adding the location of the Docker binaries to your path variable.
The suggested PowerShell code was:
[Environment]::SetEnvironmentVariable("Path", $env:Path + ";C:\Program Files\Docker", [EnvironmentVariableTarget]::Machine)
You see similar code all over the internet to do this, and even my own code I used for years used the same technique which doesn't make it any better.
It kind of works but has several problems.
I point these out using a simplified path variable value.
Consider this my original registry value under HKML\SYSTEM\CurrentControlSet\Control\Session Manager\Environment
:
There is a REG_EXPAND_SZ
value type with a name of Path
and this value:
%SystemRoot%\system32;%ToolsFolder%
at this point the value of $env:path
is:
C:\Windows\system32;D:\tools;C:\Users\name\AppData\Local\Microsoft\WindowsApps;
now run the suggest code:
[Environment]::SetEnvironmentVariable("Path", $env:Path + ";C:\Program Files\Docker", [EnvironmentVariableTarget]::Machine)
now $env:path
looks like what we expect:
C:\Windows\system32;D:\tools;C:\Users\name\AppData\Local\Microsoft\WindowsApps;C:\Program Files\Docker
but lets look at the registry again:
There is now a REG_SZ
value:
C:\Windows\system32;D:\tools;C:\Users\name\AppData\Local\Microsoft\WindowsApps;C:\Program Files\Docker
There are three problems here:
The location
C:\Users\name\AppData\Local\Microsoft\WindowsApps
has been copied from a user specific %path% entry to a machine specific one.%SystemRoot% and %ToolsFolder% are now stored as their expanded hard-coded values, not variables.
The type of the registry value changed from
REG_EXPAND_SZ
toREG_SZ
There are three problems with the suggested command, it uses the expanded string in $env:path
, not the un-expanded one with its %variables%
. $env:Path
also has user locations, it merges machine and user path values. And SetEnvironmentVariable
always creates a REG_SZ
value regardless of the existence of a REG_EXPAND_SZ
value.
So what? Is this really a problem? What if I decide to change the environment variable %ToolsFolder%
from D:\tools
to C:\Util
. In the correct setup, everything would work and C:\util
would be in the path, but now with this broken path value, none of my tools binaries are found anymore. Any other operation that expects the path value to be REG_EXPAND_SZ
may break.
The problem is that using the correct way to add a new location to the path variable requires a few more lines, not just one.
I wrote a small PowerShell script to do this without any of the problems mentioned above, using it you can do:
Set-PathVariable.ps1 -NewLocation "%ProgramFiles%\Docker"
The script is available on my GitHub page.