-
Notifications
You must be signed in to change notification settings - Fork 10
/
refrenv.ps1
319 lines (253 loc) · 12.9 KB
/
refrenv.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
# author: Badr Elmers 2021-2024
# version: 1.1
# https://github.com/badrelmers/RefrEnv
<#
NAME
RefrEnv - Refresh the Environment for Powershell/Pwsh
SYNOPSIS
. .\refrenv.ps1
DESCRIPTION
By default with no arguments, this script will do a full
refresh (refresh all non critical variables*, and refresh the PATH).
you can use the following variables to change the default behaviour:
RefrEnv_ResetPath=yes Reset the actual PATH inside Powershell, then refresh
it with a new PATH. This will delete any PATH
added by the script who called RefrEnv. It is
equivalent to running a new Powershell session.
you can also put this script in windows\systems32 or another place in your %PATH% then call it from an interactive console by writing refrenv.
*critical variables: are variables which belong to Powershell/windows and should not be refreshed normally like:
- windows vars:
ALLUSERSPROFILE APPDATA CommonProgramFiles CommonProgramFiles(x86) CommonProgramW6432 COMPUTERNAME ComSpec HOMEDRIVE HOMEPATH LOCALAPPDATA LOGONSERVER NUMBER_OF_PROCESSORS OS PATHEXT PROCESSOR_ARCHITECTURE PROCESSOR_ARCHITEW6432 PROCESSOR_IDENTIFIER PROCESSOR_LEVEL PROCESSOR_REVISION ProgramData ProgramFiles ProgramFiles(x86) ProgramW6432 PUBLIC SystemDrive SystemRoot TEMP TMP USERDOMAIN USERDOMAIN_ROAMINGPROFILE USERNAME USERPROFILE windir SESSIONNAME
#>
# based on Chocolatey powershell refreshenv
##################################################################
# Copyright © 2017 - 2021 Chocolatey Software, Inc.
# Copyright © 2015 - 2017 RealDimensions Software, LLC
# Copyright © 2011 - 2015 RealDimensions Software, LLC & original authors/contributors from https://github.com/chocolatey/chocolatey
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
function Get-EnvironmentVariableNames([System.EnvironmentVariableTarget] $Scope) {
<#
.SYNOPSIS
Gets all environment variable names.
.DESCRIPTION
Provides a list of environment variable names based on the scope. This
can be used to loop through the list and generate names.
.NOTES
Process dumps the current environment variable names in memory /
session. The other scopes refer to the registry values.
.INPUTS
None
.OUTPUTS
A list of environment variables names.
.PARAMETER Scope
The environment variable target scope. This is `Process`, `User`, or
`Machine`.
.EXAMPLE
Get-EnvironmentVariableNames -Scope Machine
.LINK
Get-EnvironmentVariable
.LINK
Set-EnvironmentVariable
#>
# Do not log function call
# HKCU:\Environment may not exist in all Windows OSes (such as Server Core).
switch ($Scope) {
'User' { Get-Item 'HKCU:\Environment' -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Property }
'Machine' { Get-Item 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Environment' | Select-Object -ExpandProperty Property }
'Process' { Get-ChildItem Env:\ | Select-Object -ExpandProperty Key }
default { throw "Unsupported environment scope: $Scope" }
}
}
# Copyright © 2017 - 2021 Chocolatey Software, Inc.
# Copyright © 2015 - 2017 RealDimensions Software, LLC
# Copyright © 2011 - 2015 RealDimensions Software, LLC & original authors/contributors from https://github.com/chocolatey/chocolatey
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
function Get-EnvironmentVariable {
<#
.SYNOPSIS
Gets an Environment Variable.
.DESCRIPTION
This will will get an environment variable based on the variable name
and scope while accounting whether to expand the variable or not
(e.g.: `%TEMP%`-> `C:\User\Username\AppData\Local\Temp`).
.NOTES
This helper reduces the number of lines one would have to write to get
environment variables, mainly when not expanding the variables is a
must.
.PARAMETER Name
The environment variable you want to get the value from.
.PARAMETER Scope
The environment variable target scope. This is `Process`, `User`, or
`Machine`.
.PARAMETER PreserveVariables
A switch parameter stating whether you want to expand the variables or
not. Defaults to false. Available in 0.9.10+.
.PARAMETER IgnoredArguments
Allows splatting with arguments that do not apply. Do not use directly.
.EXAMPLE
Get-EnvironmentVariable -Name 'TEMP' -Scope User -PreserveVariables
.EXAMPLE
Get-EnvironmentVariable -Name 'PATH' -Scope Machine
.LINK
Get-EnvironmentVariableNames
.LINK
Set-EnvironmentVariable
#>
[CmdletBinding()]
[OutputType([string])]
param(
[Parameter(Mandatory=$true)][string] $Name,
[Parameter(Mandatory=$true)][System.EnvironmentVariableTarget] $Scope,
[Parameter(Mandatory=$false)][switch] $PreserveVariables = $false,
[parameter(ValueFromRemainingArguments = $true)][Object[]] $ignoredArguments
)
# Do not log function call, it may expose variable names
## Called from chocolateysetup.psm1 - wrap any Write-Host in try/catch
[string] $MACHINE_ENVIRONMENT_REGISTRY_KEY_NAME = "SYSTEM\CurrentControlSet\Control\Session Manager\Environment\";
[Microsoft.Win32.RegistryKey] $win32RegistryKey = [Microsoft.Win32.Registry]::LocalMachine.OpenSubKey($MACHINE_ENVIRONMENT_REGISTRY_KEY_NAME)
if ($Scope -eq [System.EnvironmentVariableTarget]::User) {
[string] $USER_ENVIRONMENT_REGISTRY_KEY_NAME = "Environment";
[Microsoft.Win32.RegistryKey] $win32RegistryKey = [Microsoft.Win32.Registry]::CurrentUser.OpenSubKey($USER_ENVIRONMENT_REGISTRY_KEY_NAME)
} elseif ($Scope -eq [System.EnvironmentVariableTarget]::Process) {
return [Environment]::GetEnvironmentVariable($Name, $Scope)
}
[Microsoft.Win32.RegistryValueOptions] $registryValueOptions = [Microsoft.Win32.RegistryValueOptions]::None
if ($PreserveVariables) {
Write-Verbose "Choosing not to expand environment names"
$registryValueOptions = [Microsoft.Win32.RegistryValueOptions]::DoNotExpandEnvironmentNames
}
[string] $environmentVariableValue = [string]::Empty
try {
#Write-Verbose "Getting environment variable $Name"
if ($win32RegistryKey -ne $null) {
# Some versions of Windows do not have HKCU:\Environment
$environmentVariableValue = $win32RegistryKey.GetValue($Name, [string]::Empty, $registryValueOptions)
}
} catch {
Write-Debug "Unable to retrieve the $Name environment variable. Details: $_"
} finally {
if ($win32RegistryKey -ne $null) {
$win32RegistryKey.Close()
}
}
if ($environmentVariableValue -eq $null -or $environmentVariableValue -eq '') {
$environmentVariableValue = [Environment]::GetEnvironmentVariable($Name, $Scope)
}
return $environmentVariableValue
}
#https://github.com/chocolatey/choco/blob/f6d6140dd7abf7f99751cff6bb76c69ed834c9e7/src/chocolatey.resources/helpers/functions/Update-SessionEnvironment.ps1
# Copyright © 2017 - 2021 Chocolatey Software, Inc.
# Copyright © 2015 - 2017 RealDimensions Software, LLC
# Copyright © 2011 - 2015 RealDimensions Software, LLC & original authors/contributors from https://github.com/chocolatey/chocolatey
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
function Update-SessionEnvironment {
<#
.SYNOPSIS
Updates the environment variables of the current powershell session with
any environment variable changes that may have occured during a
Chocolatey package install.
.DESCRIPTION
When Chocolatey installs a package, the package author may add or change
certain environment variables that will affect how the application runs
or how it is accessed. Often, these changes are not visible to the
current PowerShell session. This means the user needs to open a new
PowerShell session before these settings take effect which can render
the installed application nonfunctional until that time.
Use the Update-SessionEnvironment command to refresh the current
PowerShell session with all environment settings possibly performed by
Chocolatey package installs.
.NOTES
This method is also added to the user's PowerShell profile as
`refreshenv`. When called as `refreshenv`, the method will provide
additional output.
Preserves `PSModulePath` as set by the process starting in 0.9.10.
.INPUTS
None
.OUTPUTS
None
#>
# Write-FunctionCallLogMessage -Invocation $MyInvocation -Parameters $PSBoundParameters
#ordering is important here, $user should override $machine...
$ScopeList = 'Process', 'Machine'
#powershell v2 which come preinstalled in win 7 do not have -notin
# the -notin operator is not available in the version of PowerShell running on Windows 7 system. The -notin operator was introduced in PowerShell 3.0
#To work around this issue, you can use the -notcontains operator, which is available in earlier versions of PowerShell
# TODO: i do not like this method at all, read the commit comment here for why they did it like that https://github.com/chocolatey/choco/commit/c408d1299b6f5f7e3e285d17f9e2d1719dfac122 should we really exclude User vars if we are using SYSTEM user? i aleady solved there fear about TMP by using excludedVariables so why do i need to exclude User var here? i probably do not need this check anymore but need to test it
# if ($userName -notin ('SYSTEM', "${env:COMPUTERNAME}`$")) {
# if ('SYSTEM', "${env:COMPUTERNAME}`$" -notcontains $userName) {
if (-not ($userName -contains 'SYSTEM' -or $userName -contains "${env:COMPUTERNAME}`$")) {
# but only if not running as the SYSTEM/machine in which case user can be ignored.
$ScopeList += 'User'
}
# Define a list of environment variables to exclude, this is the same list i m using in cmd
# TODO: do i need to exclude some special powershell env like i did in bash?
$excludedVariables = @(
'Path', 'ALLUSERSPROFILE', 'APPDATA', 'CommonProgramFiles', 'CommonProgramFiles(x86)',
'CommonProgramW6432', 'COMPUTERNAME', 'ComSpec', 'HOMEDRIVE', 'HOMEPATH',
'LOCALAPPDATA', 'LOGONSERVER', 'NUMBER_OF_PROCESSORS', 'OS', 'PATHEXT',
'PROCESSOR_ARCHITECTURE', 'PROCESSOR_ARCHITEW6432', 'PROCESSOR_IDENTIFIER',
'PROCESSOR_LEVEL', 'PROCESSOR_REVISION', 'ProgramData', 'ProgramFiles',
'ProgramFiles(x86)', 'ProgramW6432', 'PUBLIC', 'SystemDrive', 'SystemRoot',
'TEMP', 'TMP', 'USERDOMAIN', 'USERDOMAIN_ROAMINGPROFILE', 'USERNAME',
'USERPROFILE', 'windir', 'SESSIONNAME'
)
foreach ($Scope in $ScopeList) {
Get-EnvironmentVariableNames -Scope $Scope | ForEach-Object {
# Skip setting the PATH and the dangerous environment variables (case-insensitive comparison)
if ($excludedVariables -inotcontains $_) {
Set-Item "Env:$_" -Value (Get-EnvironmentVariable -Scope $Scope -Name $_)
}
}
}
if ($env:RefrEnv_ResetPath -eq 'yes') {
$scopes = 'Machine', 'User'
} else {
$scopes = 'Process', 'Machine', 'User'
}
#Path gets special treatment b/c it munges the two together
$paths = $scopes |
ForEach-Object {
(Get-EnvironmentVariable -Name 'PATH' -Scope $_) -split ';'
} |
Select-Object -Unique
$Env:PATH = $paths -join ';'
# PSModulePath is almost always updated by process, so we want to preserve it.
# TODO: should i exclude this? what happens when an app adds a path to PSModulePath in the hklm reg? so i think i should not prevent updating this
# $env:PSModulePath = $psModulePath
}
# Set-Alias refreshenv Update-SessionEnvironment
echo 'RefrEnv - Refresh the Environment for Powershell/Pwsh'
Update-SessionEnvironment