lib/EnvBroadcast.ps1

function Send-EnvironmentChangeBroadcast {
    <#
    .SYNOPSIS
        Sends WM_SETTINGCHANGE to all top-level windows so currently running
        applications (Explorer, terminals, IDEs) re-read their environment
        variables instead of having to be restarted.
    #>

    [CmdletBinding()]
    param()

    if (-not ('Win32.EnvHelper' -as [type])) {
        Add-Type -Namespace Win32 -Name EnvHelper -MemberDefinition @'
[System.Runtime.InteropServices.DllImport("user32.dll", SetLastError = true, CharSet = System.Runtime.InteropServices.CharSet.Auto)]
public static extern System.IntPtr SendMessageTimeout(
    System.IntPtr hWnd,
    uint Msg,
    System.UIntPtr wParam,
    string lParam,
    uint fuFlags,
    uint uTimeout,
    out System.UIntPtr lpdwResult);
'@

    }

    $HWND_BROADCAST   = [IntPtr]0xFFFF
    $WM_SETTINGCHANGE = 0x001A
    $SMTO_ABORTIFHUNG = 0x0002
    $result = [UIntPtr]::Zero

    [void][Win32.EnvHelper]::SendMessageTimeout(
        $HWND_BROADCAST,
        $WM_SETTINGCHANGE,
        [UIntPtr]::Zero,
        'Environment',
        $SMTO_ABORTIFHUNG,
        5000,
        [ref]$result
    )
}