Last active
February 25, 2016 14:51
-
-
Save Iristyle/9a870f96f1896710c01f to your computer and use it in GitHub Desktop.
Reset environment variables
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# initial stash of process vars that will overwrite Machine / User vars | |
if (! $processVars) | |
{ | |
# capture all variables by name, using whats currently available in-proc for values (already expanded) | |
$processVars = [Environment]::GetEnvironmentVariables('Process').Keys | | |
% -Begin { $h = @{} } -Process { $h.$_ = (Get-Item Env:\$_).Value } -End { $h } | |
# Write-Host "Initially captured process vars:`n`n$($processVars | Out-String)" | |
# eliminate Machine / User vars so that we have only process vars | |
'Machine', 'User' | | |
% { [Environment]::GetEnvironmentVariables($_).GetEnumerator() } | | |
? { $processVars.ContainsKey($_.Name) -and ($processVars[$_.Name] -eq $_.Value) } | | |
% { $processVars.Remove($_.Name) } | |
# Write-Host "Stored process vars:`n`n$($processVars | Out-String)" | |
} | |
# query Machine vars from registry, ensuring expansion EXCEPT for PATH | |
$vars = [Environment]::GetEnvironmentVariables('Machine').GetEnumerator() | | |
% -Begin { $h = @{} } -Process { $v = if ($_.Name -eq 'Path') { $_.Value } else { [Environment]::GetEnvironmentVariable($_.Name, 'Machine') }; $h."$($_.Name)" = $v } -End { $h } | |
# Write-Host "Read MACHINE vars:`n`n$($vars | Out-String)" | |
# query User vars from registry, ensuring expansion EXCEPT for PATH | |
[Environment]::GetEnvironmentVariables('User').GetEnumerator() | | |
% { | |
if ($_.Name -eq 'Path') { $vars[$_.Name] += ';' + $_.Value } | |
else | |
{ | |
$value = [Environment]::GetEnvironmentVariable($_.Name, 'User') | |
$vars[$_.Name] = $value | |
# Write-Host "Re-read $($_.Name) from User as $value / stored as $($vars[$_.Name])" | |
} | |
} | |
# Write-Host "Vars updated with USER vars:`n`n$($vars | Out-String)" | |
$processVars.GetEnumerator() | % { $vars[$_.Name] = $_.Value } | |
# Write-Host "Vars updated with Process vars:`n`n$($vars | Out-String)" | |
Remove-Item Env:\* | |
$vars.GetEnumerator() | | |
% { Set-Item -Path "Env:\$($_.Name)" -Value $_.Value } |
https://gist.github.com/Iristyle/9a870f96f1896710c01f#file-env-reset-ps1-L11
Note, this is going to destroy $env:PSMODULEPATH
. We would need to skip this one.
Oh sweet, capturing the Process variables 👍
After line 40 $processVars has 26 items, wheres (ls env:).Count has 38. The variables missing cripple the shell to the point where the process crashes. Still figuring out what is missing here
$vars
has the full process list, but still the process crashes after line 44
The fix, strangely enough, was to sort the $processVars
by Name before attempting to pass it to the next block. This originates from passing the results of the inner PS session $processVars
to the outer PS session, then back into the inner PS session later on.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
One interesting thing to note is that the restored environment has unexpanded environment variables (which is OK / expected forPATH
), but might be a problem inComSpec
andwindir
- so there might need to be special handling there. CallingGetEnvironmentVariable
will expand, whileGetEnvironmentVariables
does not expand.I have modified the code so that everything is captured / reinstated verbatim, including observing existing behavior around which variables are expanded, etc.