user2099834
user2099834

Reputation: 33

Machine level environment variable not available after setting in Powershell

The following code does not return "Y" as expected. Only in the next session (another new window) it works? I would expect it to be available immediately?

    [Environment]::SetEnvironmentVariable("X", "Y", "Machine")
    Write-Host $env:X

Upvotes: 2

Views: 2008

Answers (2)

majkinetor
majkinetor

Reputation: 9056

You must do this since the process gets env vars on start, not while running (i.e. you would have to restart shell for this to work your way):

 [Environment]::SetEnvironmentVariable("X", "Y", "Machine")
 $Env:X = "Y"

There is also a way to broadcast this to other windows using WM_SETTINGCHANGE

To effect a change in the environment variables for the system or the user, broadcast this message with lParam set to the string "Environment".)

# Notify system of change via WM_SETTINGCHANGE
    if (! ("Win32.NativeMethods" -as [Type]))
    {
        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);
"@
    }

    $HWND_BROADCAST = [IntPtr] 0xffff; $WM_SETTINGCHANGE = 0x1a; $result = [UIntPtr]::Zero
    [Win32.Nativemethods]::SendMessageTimeout($HWND_BROADCAST, $WM_SETTINGCHANGE, [UIntPtr]::Zero, "Environment", 2, 5000, [ref] $result) | out-null
}

Upvotes: 1

Martin Brandl
Martin Brandl

Reputation: 59031

As far as I know, a process loads the environment variables only once (at start). But you can change it using:

[Environment]::SetEnvironmentVariable("X", "Y", "Process") # for the current session

Note: You probably want to set both:

[Environment]::SetEnvironmentVariable("X", "Y", "Machine")
[Environment]::SetEnvironmentVariable("X", "Y", "Process")

Upvotes: 1

Related Questions