Skip to content

Instantly share code, notes, and snippets.

@espresso3389
Last active May 18, 2026 08:12
Show Gist options
  • Select an option

  • Save espresso3389/a59eae40b6a0b460fbd510b2dfe3564d to your computer and use it in GitHub Desktop.

Select an option

Save espresso3389/a59eae40b6a0b460fbd510b2dfe3564d to your computer and use it in GitHub Desktop.
A PowerShell script (for Windows), that updates the environment variables; not only the process but the user's environment variables
$envs = @{
#"CHROME_EXECUTABLE" = "%ProgramFiles%\Google\Chrome Dev\Application\chrome.exe"
"PACKAGES_ROOT" = "D:\.packages"
"PUB_CACHE" = "%PACKAGES_ROOT%\pub"
"npm_config_cache" = "%PACKAGES_ROOT%\npm"
"NUGET_PACKAGES" = "%PACKAGES_ROOT%\nuget"
"BUN_INSTALL_CACHE_DIR" = "%PACKAGES_ROOT%\bun\install\cache"
"VCPKG_DEFAULT_BINARY_CACHE" = "%PACKAGES_ROOT%\vcpkg"
"PIP_CACHE_DIR" = "%PACKAGES_ROOT%\pip"
"GRADLE_USER_HOME" = "%PACKAGES_ROOT%\.gradle"
"MAVEN_OPTS" = "-Dmaven.repo.local=%PACKAGES_ROOT%\maven %MAVEN_OPTS%"
"JAVA_HOME"="%ProgramFiles%\Android\Android Studio\jbr"
"CLAUDE_CODE_GIT_BASH_PATH"="%ProgramFiles%\git\bin\bash.exe"
}
$path = @(
"%USERPROFILE%\.bun\bin"
"%USERPROFILE%\.local\bin"
"D:\flutter\bin"
"%LOCALAPPDATA%\Android\Sdk\platform-tools"
"%PUB_CACHE%\bin"
"%JAVA_HOME%\bin"
)
# Function to expand environment variables in a string
function Expand-EnvironmentVariables {
param([string]$Value)
return [System.Environment]::ExpandEnvironmentVariables($Value)
}
# Function to broadcast environment variable changes
function Send-EnvironmentChangeMessage {
if (-not ('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, # SMTO_ABORTIFHUNG
5000,
[ref]$result
) | Out-Null
}
# Set environment variables to User registry (without expansion)
$changesCount = 0
foreach ($entry in $envs.GetEnumerator()) {
$key = $entry.Key
$value = $entry.Value
# Check if the value is different from current registry value (unexpanded)
$regKey = [Microsoft.Win32.Registry]::CurrentUser.OpenSubKey("Environment", $false)
$currentValue = if ($regKey) {
$regKey.GetValue($key, $null, [Microsoft.Win32.RegistryValueOptions]::DoNotExpandEnvironmentNames)
} else {
$null
}
if ($regKey) { $regKey.Close() }
if ($currentValue -ne $value) {
# Determine registry type based on whether value contains expandable variables
$regType = if ($value -match '%\w+%') { 'ExpandString' } else { 'String' }
# Set in user registry using Set-ItemProperty
Set-ItemProperty -Path "HKCU:\Environment" -Name $key -Value $value -Type $regType
$changesCount++
}
# Expand for display and current process
$expandedValue = Expand-EnvironmentVariables $value
# Set in current process (expanded)
Set-Item -Path "env:$key" -Value $expandedValue
}
# Get current user PATH from registry (unexpanded)
$regKey = [Microsoft.Win32.Registry]::CurrentUser.OpenSubKey("Environment", $false)
$currentUserPath = if ($regKey) {
$regKey.GetValue("Path", "", [Microsoft.Win32.RegistryValueOptions]::DoNotExpandEnvironmentNames)
} else {
""
}
if ($regKey) { $regKey.Close() }
# Convert to array and filter out empties
$pathArray = if ($currentUserPath) {
$currentUserPath -split ';' | Where-Object { $_ -ne '' }
} else {
@()
}
# Add new paths if they don't already exist (compare expanded versions)
$pathModified = $false
$expandedPathArray = $pathArray | ForEach-Object { Expand-EnvironmentVariables $_ }
$newPathArray = @()
foreach ($newPath in $path) {
$expandedNewPath = Expand-EnvironmentVariables $newPath
if ($expandedPathArray -notcontains $expandedNewPath) {
$newPathArray += $newPath
$expandedPathArray += $expandedNewPath
$pathModified = $true
}
}
# Update user PATH in registry if modified
if ($pathModified) {
$newUserPath = ($newPathArray + $pathArray) -join ';'
Set-ItemProperty -Path "HKCU:\Environment" -Name "Path" -Value $newUserPath -Type ExpandString
$changesCount++
}
# Update current process PATH with expanded values
$processPathArray = @()
foreach ($p in $pathArray) {
$expanded = Expand-EnvironmentVariables $p
if ($expanded) {
$processPathArray += $expanded
}
}
# Add existing system paths to avoid breaking current session
$systemPath = [System.Environment]::GetEnvironmentVariable("Path", [System.EnvironmentVariableTarget]::Machine)
if ($systemPath) {
$systemPaths = $systemPath -split ';' | Where-Object { $_ -ne '' }
foreach ($sysPath in $systemPaths) {
if ($processPathArray -notcontains $sysPath) {
$processPathArray += $sysPath
}
}
}
$env:Path = $processPathArray -join ';'
# Broadcast the environment change to all windows only if changes were made
if ($changesCount -gt 0) {
Send-EnvironmentChangeMessage
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment