3

I am trying to use powershell to update Windows system path by :

$oldpath = (Get-ItemProperty -Path ‘Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment’ -Name PATH).path
$newpath = "$oldpath;C:\nuget"
Write-Output "PATH:$newpath"
Set-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment' -Name PATH -Value $newPath -Force
Get-ItemProperty -Path ‘Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment’ -Name PATH   

it seems work, Get-ItemProperty does show "C:\nuget" is added into path. The problem is then i start a new powershell console or a command line console, and type "nuget", I still get "The term 'nuget' is not recognized as the name of a cmdlet, function, script file, or operable program"

in the new powershell console, if I rerun Get-ItemProperty, it shows the new Path is there, it's just doesn't immediately take effect in current user session. If I run "set " in cmd console, the new Path wasn't there in PATH variable.

BTW, after Set-ItemProperty was run, I checked control pannel->System->Advanced system setting->Environment Variables, the new Path I added is there.

I found if I manually modify the Path through Windows system setting, it will take effect immediately ( new cmd/powershell will have it); but if the path is modified by powershell Set-ItemProperty command, then I have to logoff, then login, then new Path will take effect.

Feels like the system Path is cached in the current user login session.

3
  • would like to find a way to make the new PATH take effect in current user session. Sep 27, 2017 at 19:30
  • It may feel like caching but it's inheriting from systemenvironment on creation/spawning. Chocolatey has a cmdlet Update-SessionEnvironment with the alias refreshenv which does what the name promises.
    – LotPings
    Sep 27, 2017 at 20:12
  • Tried the Update-SessionEnvironment and it doesn't work for me. This script's description says "Use the Update-SessionEnvironment command to refresh the current PowerShell session". My issue was not in current powershell session ( That can be fixed by $env:Path += ";C:\nuget" ). My issue is once a new Path is added by Set-ItemProperty, it doesn't take effect in any new cmd or powershell, untill I logoff/login. Sep 27, 2017 at 20:43

2 Answers 2

4

When you change the PATH variable by using the control panel, when you click "OK", the control panel sends a WM_SETTINGCHANGE message to all the opened windows, so they know that the environments variables has been changed.

So, if you don't want to logoff, you must send WM_SETTINGCHANGE yourself by creating/finding a little program that sends this message according to the documentation: https://msdn.microsoft.com/en-us/library/windows/desktop/ms725497%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396

1
1

Just want to post a complete answer from https://mnaoumov.wordpress.com/2012/07/24/powershell-add-directory-to-environment-path-variable/ , following powershell script will do the trick :

    Set-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment' -Name PATH -Value $newPath -Force

    $HWND_BROADCAST = [IntPtr] 0xffff;
    $WM_SETTINGCHANGE = 0x1a;
    $result = [UIntPtr]::Zero

    if (-not ("Win32.NativeMethods" -as [Type]))
    {
        # import sendmessagetimeout from win32
        Add-Type -Namespace Win32 -Name NativeMethods -MemberDefinition @"
        [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        public static extern IntPtr SendMessageTimeout(
        IntPtr hWnd, uint Msg, UIntPtr wParam, string lParam,
        uint fuFlags, uint uTimeout, out UIntPtr lpdwResult);
"@
    }
    # notify all windows of environment block change
    [Win32.Nativemethods]::SendMessageTimeout($HWND_BROADCAST, $WM_SETTINGCHANGE, [UIntPtr]::Zero, "Environment", 2, 5000, [ref] $result);

1
  • Warning: This script did not work for me and cleared my system Path variable in the registry, which broke many things on my machine. Fortunately, I had left an old terminal open and was able to recover it. If you try this script, be careful and/or make sure to copy your Path var as a backup.
    – ABabin
    Feb 19, 2022 at 17:54

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .