我发现设置PATH环境变量只影响旧的命令提示符。PowerShell似乎有不同的环境设置。如何更改PowerShell (v1)的环境变量?
注意:
我希望我的更改是永久性的,这样我就不必每次运行PowerShell时都设置它。PowerShell有配置文件吗?比如Unix上的Bash配置文件?
我发现设置PATH环境变量只影响旧的命令提示符。PowerShell似乎有不同的环境设置。如何更改PowerShell (v1)的环境变量?
注意:
我希望我的更改是永久性的,这样我就不必每次运行PowerShell时都设置它。PowerShell有配置文件吗?比如Unix上的Bash配置文件?
当前回答
这些脚本是幂等的(可以运行多次)。 它们更新Windows路径和当前/未来的Powershell会话:
永久添加路径
$targetDir="c:\bin"
$oldPath = [System.Environment]::GetEnvironmentVariable("Path","Machine")
$oldPathArray=($oldPath) -split ';'
if(-Not($oldPathArray -Contains "$targetDir")) {
write-host "Adding $targetDir to Machine Path"
$newPath = "$oldPath;$targetDir" -replace ';+', ';'
[System.Environment]::SetEnvironmentVariable("Path",$newPath,"Machine")
$env:Path = [System.Environment]::GetEnvironmentVariable("Path","User"),[System.Environment]::GetEnvironmentVariable("Path","Machine") -join ";"
}
write-host "Windows paths:"
($env:Path).Replace(';',"`n")
永久删除路径
$targetDir="c:\bin"
$oldPath = [System.Environment]::GetEnvironmentVariable("Path","Machine")
$oldPathArray=($oldPath) -split ';'
if($oldPathArray -Contains "$targetDir") {
write-host "Removing $targetDir from Machine path"
$newPathArray = $oldPathArray | Where-Object { $_ –ne "$targetDir" }
$newPath = $newPathArray -join ";"
[System.Environment]::SetEnvironmentVariable("Path",$newPath,"Machine")
$env:Path = [System.Environment]::GetEnvironmentVariable("Path","User"),[System.Environment]::GetEnvironmentVariable("Path","Machine") -join ";"
}
write-host "Windows paths:"
($env:Path).Replace(';',"`n")
其他回答
虽然目前接受的答案在某种意义上是路径变量从PowerShell的上下文中被永久更新,但它实际上并不更新存储在Windows注册表中的环境变量。
要实现这一点,你显然也可以使用PowerShell:
$oldPath=(Get-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment' -Name PATH).Path
$newPath=$oldPath+’;C:\NewFolderToAddToTheList\’
Set-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment' -Name PATH –Value $newPath
更多信息请参见博文《使用PowerShell修改环境路径》
如果您使用PowerShell社区扩展,为环境变量path添加路径的正确命令是:
Add-PathVariable "C:\NewFolderToAddToTheList" -Target Machine
就像JeanT的回答一样,我想要一个关于添加路径的抽象。与JeanT的回答不同,我需要它在没有用户交互的情况下运行。我寻找的其他行为:
更新$env:Path,使更改在当前会话中生效 为以后的会话持久化环境变量更改 当相同的路径已经存在时,不添加重复的路径
如果有用的话,这里是:
function Add-EnvPath {
param(
[Parameter(Mandatory=$true)]
[string] $Path,
[ValidateSet('Machine', 'User', 'Session')]
[string] $Container = 'Session'
)
if ($Container -ne 'Session') {
$containerMapping = @{
Machine = [EnvironmentVariableTarget]::Machine
User = [EnvironmentVariableTarget]::User
}
$containerType = $containerMapping[$Container]
$persistedPaths = [Environment]::GetEnvironmentVariable('Path', $containerType) -split ';'
if ($persistedPaths -notcontains $Path) {
$persistedPaths = $persistedPaths + $Path | where { $_ }
[Environment]::SetEnvironmentVariable('Path', $persistedPaths -join ';', $containerType)
}
}
$envPaths = $env:Path -split ';'
if ($envPaths -notcontains $Path) {
$envPaths = $envPaths + $Path | where { $_ }
$env:Path = $envPaths -join ';'
}
}
检查我的要点对应的Remove-EnvPath函数。
基于@Michael Kropat的回答,我添加了一个参数,将新路径前置到现有的path变量中,并检查以避免添加不存在的路径:
function Add-EnvPath {
param(
[Parameter(Mandatory=$true)]
[string] $Path,
[ValidateSet('Machine', 'User', 'Session')]
[string] $Container = 'Session',
[Parameter(Mandatory=$False)]
[Switch] $Prepend
)
if (Test-Path -path "$Path") {
if ($Container -ne 'Session') {
$containerMapping = @{
Machine = [EnvironmentVariableTarget]::Machine
User = [EnvironmentVariableTarget]::User
}
$containerType = $containerMapping[$Container]
$persistedPaths = [Environment]::GetEnvironmentVariable('Path', $containerType) -split ';'
if ($persistedPaths -notcontains $Path) {
if ($Prepend) {
$persistedPaths = ,$Path + $persistedPaths | where { $_ }
[Environment]::SetEnvironmentVariable('Path', $persistedPaths -join ';', $containerType)
}
else {
$persistedPaths = $persistedPaths + $Path | where { $_ }
[Environment]::SetEnvironmentVariable('Path', $persistedPaths -join ';', $containerType)
}
}
}
$envPaths = $env:Path -split ';'
if ($envPaths -notcontains $Path) {
if ($Prepend) {
$envPaths = ,$Path + $envPaths | where { $_ }
$env:Path = $envPaths -join ';'
}
else {
$envPaths = $envPaths + $Path | where { $_ }
$env:Path = $envPaths -join ';'
}
}
}
}
这些脚本是幂等的(可以运行多次)。 它们更新Windows路径和当前/未来的Powershell会话:
永久添加路径
$targetDir="c:\bin"
$oldPath = [System.Environment]::GetEnvironmentVariable("Path","Machine")
$oldPathArray=($oldPath) -split ';'
if(-Not($oldPathArray -Contains "$targetDir")) {
write-host "Adding $targetDir to Machine Path"
$newPath = "$oldPath;$targetDir" -replace ';+', ';'
[System.Environment]::SetEnvironmentVariable("Path",$newPath,"Machine")
$env:Path = [System.Environment]::GetEnvironmentVariable("Path","User"),[System.Environment]::GetEnvironmentVariable("Path","Machine") -join ";"
}
write-host "Windows paths:"
($env:Path).Replace(';',"`n")
永久删除路径
$targetDir="c:\bin"
$oldPath = [System.Environment]::GetEnvironmentVariable("Path","Machine")
$oldPathArray=($oldPath) -split ';'
if($oldPathArray -Contains "$targetDir") {
write-host "Removing $targetDir from Machine path"
$newPathArray = $oldPathArray | Where-Object { $_ –ne "$targetDir" }
$newPath = $newPathArray -join ";"
[System.Environment]::SetEnvironmentVariable("Path",$newPath,"Machine")
$env:Path = [System.Environment]::GetEnvironmentVariable("Path","User"),[System.Environment]::GetEnvironmentVariable("Path","Machine") -join ";"
}
write-host "Windows paths:"
($env:Path).Replace(';',"`n")
我的建议是:
我已经测试了将C:\oracle\x64\bin永久地添加到环境变量Path中,这工作正常。
$ENV:PATH
第一种方法很简单:
$ENV:PATH=”$ENV:PATH;c:\path\to\folder”
但这种改变不是永久的。$env:path将在关闭PowerShell终端并重新打开时默认恢复到之前的状态。这是因为您在会话级别而不是源级别(即注册表级别)应用了更改。要查看$env:path的全局值,请执行以下操作:
Get-ItemProperty -Path ‘Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment’ -Name PATH
或者更具体地说:
(Get-ItemProperty -Path ‘Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment’ -Name PATH).path
现在要改变这一点,首先我们捕获需要修改的原始路径:
$oldpath = (Get-ItemProperty -Path ‘Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment’ -Name PATH).path
现在我们定义新的路径应该是什么样的。在本例中,我们添加了一个新文件夹:
$newpath = “$oldpath;c:\path\to\folder”
注意:请确保$newpath看起来是您想要的样子。如果不是,那么你可能会损坏你的操作系统。
现在应用新值:
Set-ItemProperty -Path ‘Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment’ -Name PATH -Value $newPath
现在做最后一次检查,它看起来像你期望的那样:
(Get-ItemProperty -Path ‘Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment’ -Name PATH).Path
现在可以重新启动PowerShell终端(甚至重新启动计算机),并看到它不会再次回滚到旧值。
注意路径的顺序可能会改变,所以它是按字母顺序排列的,所以一定要检查整行。为了更简单,你可以使用分号作为分隔符将输出分成行:
($env:path).split(“;”)