1

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.

  • would like to find a way to make the new PATH take effect in current user session. – jack.chen.job Sep 27 '17 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 '17 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. – jack.chen.job Sep 27 '17 at 20:43
2

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

0

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);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.