文章目录
- powershell操作环境变量
- 范围说明
- 更新环境变量
- 添加环境变量
- 移除指定的环境变量
- 修改环境变量
powershell操作环境变量
- 所作修改长期有效,重启仍然有效
- 关于查看环境变量,另见它文
范围说明
- 以下函数支持用户级别和系统级别的更改
- 默认更改用户级别,系统级别的更改需要以管理员方式运行shell才行
- 总的来说,这些函数调用简单有效,能够自动更新当前powershell中的环境变量
更新环境变量
function Update-EnvVar
{
<#
.SYNOPSIS
更新所有环境变量的修改(包括添加新值/移除已有值/修改值),并且会指出那些环境变量被修改了以及修改前后是什么样的
鉴于Path变量的特殊性,本函数不会处理Path变量
Update-EnvVar本身不会修改[Environment]中的环境变量,即不会影响系统保存的环境变量,无论是用户级还是系统,只更新当前shell中的环境变量
对于多个shell窗口同时发生修改环境变量的情形时很有用,当然如果您习惯用GUI修改环境变量,本方法也可以将您的修改同步到当前shell(除了Path变量外)
通常调用Set-EnvVar 或Add-EnvVar 更改var环境变量时,会自动更新当前shell的var环境变量($env:var查询到的值)
但是如果在多个不同的shell窗口内分别调用了Set-EnvVar或Add-EnvVar,那么可能会造成变量信息的不一致
为了避免这种情况,可以调用此函数更新所有shell的环境变量
注意本函数以[Environment]对象中存储的环境变量信息为准,如果当前shell的环境变量不同于[Environment]中查询到的那样,则会更新为[Environment]中查询到的值
如果当前shell有不存在于[Environment]中的环境变量,则认为是改shell环境的临时环境变量,调用本函数并不会更改或影响到这些变量
这些情况是存在的,有些场合下我们只需要创建临时的环境变量而不需要写入系统保存
默认读取的是User级别的环境变量
.#>
param(
$Scope = 'User'
)
$envs = [System.Environment]::GetEnvironmentVariables($Scope)
$envs.GetEnumerator() | Where-Object { $_.Key -ne 'Path' } | ForEach-Object {
# Write-Output "$($_.Name)=$($_.Value)"
$env_left = "`$env:$($_.Name)"
$expressoin = "$env_left='$($_.Value)'"
$current_value = $env_left | Invoke-Expression
if ($current_value -ne $_.Value)
{
Write-Host "$env_left from [$(Invoke-Expression($env_left))] `t to `t [$($_.Value)]" -BackgroundColor Magenta
$expressoin | Invoke-Expression
}
}
}
添加环境变量
function Add-EnvVar
{
<#
.SYNOPSIS
添加环境变量(包括创建新变量及其取值,为已有变量添加取值),并且立即更新所作的更改
这里我们利用$expression | Invoke-Expression等方法来手动立即更新当前powershell上下文的环境变量,实现不需要重启更新环境变量
👺为了确保一致性,且无在不同的powershell窗口分别使用本函数,否则会造成修改覆盖造成修改丢失
虽然本函数能够刷新当前powershell上下文的环境变量,但是其他shell进程却不会跟着刷新
当对一个已经存在变量添加值时,会在头部插入新值;(有些时候末尾会带有分号,导致查询出来的值可能存在2个来连续的分号)
这时候可以判断移除最后一个分号,然后再添加新值,头插方式也行
.EXAMPLE
PS BAT [10:58:25 PM] [C:\Users\cxxu\Desktop]
[🔋 100%] MEM:72.79% [5.71/7.85] GB |add-envVar -env_var new2 -new_value v2
v2
.EXAMPLE
PS BAT [10:58:33 PM] [C:\Users\cxxu\Desktop]
[🔋 100%] MEM:72.74% [5.71/7.85] GB |add-envVar -env_var new2 -new_value v3 -V
$env:new2 = 'v2;v3'
v2;v3
.EXAMPLE
以管理员权限运行powershell,可以配置系统级别的环境变量
PS BAT [11:16:24 PM] [C:\Users\cxxu\Desktop]
[🔋 100%] MEM:73.80% [5.79/7.85] GB |add-envVar -env_var new -new_value v1 -Scope Machine
v1
.EXAMPLE
PS>(Get-EnvVar -Key Path -Scope U|select -ExpandProperty value) -split ';'
C:\Program Files\PowerShell\7
C:\Users\cxxu\scoop\shims
C:\Users\cxxu\AppData\Local\Programs\oh-my-posh\bin
C:\Users\cxxu\.dotnet\tools
PS>Add-EnvVar -env_var Path -Scope User -new_value NewValueDemo
NewValueDemo;C:\Program Files\PowerShell\7;C:\Users\cxxu\scoop\shims;C:\Users\cxxu\AppData\Local\Programs\oh-my-posh\bin;C:\Users\cxxu\.dotnet\tools;
PS>(Get-EnvVar -Key Path -Scope U|select -ExpandProperty value) -split ';'
NewValueDemo
C:\Program Files\PowerShell\7
C:\Users\cxxu\scoop\shims
C:\Users\cxxu\AppData\Local\Programs\oh-my-posh\bin
C:\Users\cxxu\.dotnet\tools
#>
param (
$env_var = 'new',
$new_value = 'demo_new',
# choose User or Machine,the former is default(no need for Administrator priviledge)
# the Machine scope need Administrator priviledge
[ValidateSet('Machine', 'User')]
$Scope = 'User',
[switch]$V,
[switch]$Query
)
# 同步环境变量
Update-EnvVar -Scope $Scope
# 先获取当前用户或机器级别的 环境变量 值
$current_value = [Environment]::GetEnvironmentVariable($env_var, $Scope)
#查询当前值,能够区分不同Scope的环境变量(例如用户变量和系统变量都有Path,如果只想插入一个新值到用户Path,就要用上述方法访问)
# $current_value = "`$env:$env_var" | Invoke-Expression #无法区分用户和系统的path变量
# 添加新路径到现有 Path
#$current_value如果没有提前设置值,则返回null,而不是'',不能用$current_value -ne '' 判断是否新变量,直接用$current_value 即可
$new_value = $current_value ? "$new_value;$current_value" : $new_value
# Write-Output $new_value
# 清除当前会话的 Path 缓存变量
# '$env:' + "$env_var" + '="new_value"' |iex
# Write-Output
$env_left = "`$env:$env_var"
$expression = "$env_left = '$new_value'"
if ($V -or $Query)
{
Write-Host $expression -BackgroundColor green
}
if ($Query)
{
$replay = Read-Host -Prompt 'Enter y to continue,else exit '
if ($replay -ne 'y')
{
return
}
}
# 设置 Scope 级别的 Path 环境变量
[Environment]::SetEnvironmentVariable($env_var, $new_value, $Scope)
# 刷新当前shell的环境变量
$expression | Invoke-Expression
# return $new_value
Write-Host "$($env_left)=$new_value" -BackgroundColor Yellow
}
移除指定的环境变量
function Remove-EnvVar
{
<#
.SYNOPSIS
移除环境变量
.EXAMPLE
批量移除(借助Get-EnvVar 和管道符可以先做模糊匹配,然后通过foreach(%)循环删除,即便本函数暂不支持直接接受管道符输入):
Get-EnvVar new*|select name|%{Remove-EnvVar -env_var $_.Name}
#>
param (
$env_var = '',
# choose User or Machine,the former is default(no need for Administrator priviledge)
# the Machine scope need Administrator priviledge
[ValidateSet('Machine', 'User')]
$Scope = 'User'
)
$current_value = "`$env:$env_var" | Invoke-Expression
#虽然也可以考虑用Get-EnvVar -key $env_var|select value 查询当前值,但这不一定都是已经生效的值
# 添加新路径到现有 Path
#$current_value如果没有提前设置值,则返回null,而不是'',不能用$current_value -ne '' 判断是否新变量,直接用$current_value 即可
$new_value = $current_value ? "$current_value;$new_value" : $new_value
# Write-Output $new_value
# $expression = "`$env:$env_var = '$new_value'"
#当前shell上下文中移掉该环境变量
if ("`$env:$env_var" | Invoke-Expression)
{
# 设置 Scope 级别的 Path 环境$env_var变量为空,从而清除该环境变量(.Net检测到空字符串就移除掉该变量,而不仅仅设置为空字符串)
[Environment]::SetEnvironmentVariable($env_var, '', $Scope)
Remove-Item env:$env_var
}
else
{
Write-Host "No [$env_var] was found! Nothing to Remove."
}
}
修改环境变量
- 组合调用上述两个函数即可
function Set-EnvVar
{
<#
.SYNOPSIS
将已有的环境变量值做修改(增/改/删)
如果只希望对已有的环境变量添加一个值,例如Path变量追加一个取值,则使用Add-EnvVar处理
如果想要编辑多个值的变量,例如修改Path变量(删除它的一个路径值),这类情况建议打开gui操作
当然本命令也是可以改的,在终端中处理字符串却不会比GUI容易执行这类修改
.EXAMPLE
#将new3这个环境变量设置为v3p,无论原来的值是多少(如果原来没有这个环境变量,则新添加一个环境变量)
Set-EnvVar -env_var new3 -new_value v3p
.EXAMPLE
PS>Set-EnvVar -env_var new3 -new_value v3R
v3R
PS>$env:new3
v3R
PS>Set-EnvVar -env_var new3 -new_value v3S
v3S
PS>$env:new3
v3S
.EXAMPLE
PS>$env:new100
PS>Set-EnvVar -env_var new100 -new_value v100
v100
PS>$env:new100
v100
.EXAMPLE
#移除环境变量
PS>Set-EnvVar -env_var new100 -new_value ''
PS>$env:new100
PS>
#>
param (
$env_var = '',
$new_value = 'new_value',
$Scope = 'User'
)
#移除旧值(如果旧值非空的话)
Remove-EnvVar -env_var $env_var -Scope $Scope
#添加新值
Add-EnvVar -env_var $env_var -new_value $new_value -Scope $Scope
}