我发现设置PATH环境变量只影响旧的命令提示符。PowerShell似乎有不同的环境设置。如何更改PowerShell(v1)的环境变量?
注意:
我想使我的更改永久生效,这样我就不必每次运行PowerShell时都设置它。PowerShell是否有配置文件?就像Unix上的Bash配置文件一样?
我发现设置PATH环境变量只影响旧的命令提示符。PowerShell似乎有不同的环境设置。如何更改PowerShell(v1)的环境变量?
注意:
我想使我的更改永久生效,这样我就不必每次运行PowerShell时都设置它。PowerShell是否有配置文件?就像Unix上的Bash配置文件一样?
在@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 ';'
}
}
}
}
Path
)。以下函数对于 Path
/ PSModulePath
和 User
/ System
类型都适用。默认情况下,它还将新路径添加到当前会话中。function AddTo-Path {
param (
[string]$PathToAdd,
[Parameter(Mandatory=$true)][ValidateSet('System','User')][string]$UserType,
[Parameter(Mandatory=$true)][ValidateSet('Path','PSModulePath')][string]$PathType
)
# AddTo-Path "C:\XXX" "PSModulePath" 'System'
if ($UserType -eq "System" ) { $RegPropertyLocation = 'HKLM:\System\CurrentControlSet\Control\Session Manager\Environment' }
if ($UserType -eq "User" ) { $RegPropertyLocation = 'HKCU:\Environment' } # also note: Registry::HKEY_LOCAL_MACHINE\ format
$PathOld = (Get-ItemProperty -Path $RegPropertyLocation -Name $PathType).$PathType
"`n$UserType $PathType Before:`n$PathOld`n"
$PathArray = $PathOld -Split ";" -replace "\\+$", ""
if ($PathArray -notcontains $PathToAdd) {
"$UserType $PathType Now:" # ; sleep -Milliseconds 100 # Might need pause to prevent text being after Path output(!)
$PathNew = "$PathOld;$PathToAdd"
Set-ItemProperty -Path $RegPropertyLocation -Name $PathType -Value $PathNew
Get-ItemProperty -Path $RegPropertyLocation -Name $PathType | select -ExpandProperty $PathType
if ($PathType -eq "Path") { $env:Path += ";$PathToAdd" } # Add to Path also for this current session
if ($PathType -eq "PSModulePath") { $env:PSModulePath += ";$PathToAdd" } # Add to PSModulePath also for this current session
"`n$PathToAdd has been added to the $UserType $PathType"
}
else {
"'$PathToAdd' is already in the $UserType $PathType. Nothing to do."
}
}
# Add "C:\XXX" to User Path (but only if not already present)
AddTo-Path "C:\XXX" "User" "Path"
# Just show the current status by putting an empty path
AddTo-Path "" "User" "Path"
在 PowerShell 中,可以通过输入以下命令来导航到环境变量目录:
Set-Location Env:
Env:\> Get-ChildItem
Env:\> $Env:<variable name>, e.g. $Env:Path
要设置环境变量,请输入:
Env:\> $Env:<variable name> = "<new-value>", e.g. $Env:Path="C:\Users\"
要删除环境变量,请输入:
Env:\> remove-item Env:<variable name>, e.g. remove-item Env:SECRET_KEY
更多信息请参阅关于环境变量的介绍。
正如Jonathan Leaders在这里所提到的那样,为了能够更改'machine'环境变量,必须以管理员身份运行命令/脚本,但是并不需要使用Community Extensions来以管理员身份运行某些命令,因此我想修改和扩展JeanT的答案,使即使未以管理员身份运行脚本本身也可以执行更改机器变量的操作:
function Set-Path ([string]$newPath, [bool]$permanent=$false, [bool]$forMachine=$false )
{
$Env:Path += ";$newPath"
$scope = if ($forMachine) { 'Machine' } else { 'User' }
if ($permanent)
{
$command = "[Environment]::SetEnvironmentVariable('PATH', $env:Path, $scope)"
Start-Process -FilePath powershell.exe -ArgumentList "-noprofile -command $Command" -Verb runas
}
}
明确一下,Windows 90年代的方式是点击 开始,右键点击此电脑,选择属性,在弹出的对话框中选择高级系统设置,然后在列表中双击PATH,使用新建,编辑,上移和下移来更改PATH环境变量。PowerShell和Windows中的其余部分都会使用您在此处设置的内容。
是的,您可以使用这些新方法,但旧方法仍然有效。在基本层面上,所有永久更改方法都是通过编辑您的注册表文件进行控制的。
大多数答案没有涉及到用户账户控制(UAC)。本文将讨论UAC问题。
首先,通过http://chocolatey.org/安装PowerShell社区扩展:choco install pscx
(您可能需要重新启动您的shell环境)。
然后启用pscx。
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser #allows scripts to run from the interwebs, such as pcsx
Invoke-Elevated
。Invoke-Elevated {Add-PathVariable $args[0] -Target Machine} -ArgumentList $MY_NEW_DIR
C:\vcpkg
永久性地 添加到我的 PATH
环境变量中,而没有任何不良影响:$current_PATH = [Environment]::GetEnvironmentVariable("PATH", "USER");[Environment]::SetEnvironmentVariable("PATH", "$current_PATH;C:\vcpkg;", "USER")
您可以将"USER"
更改为"MACHINE"
以更改系统环境变量(需要管理员终端,您可能需要将Environment
更改为System.Environment
),甚至可以将其更改为"PROCESS"
以仅更改本地PATH
环境变量(不会永久更改)。相应的"USER"=1
"MACHINE"=2
和 "PROCESS"=0
,这里是关于这些命令的文档:GetEnvironmentVariable,SetEnvironmentVariable
我发现了另外两个答案,但有重大缺陷,不建议使用。两者均使用SETX
作为PowerShell实现来永久更改环境变量。这些命令的缺点是您将复制系统PATH到您的本地路径并且需要PowerShell才能使用它们:
setx PATH "$($Env:PATH);C:\vcpkg;"
更长,但允许与其他环境变量一起使用:
$($Env:PATH).Split(';') | %{ $str += "$($_.Trim('"'));" }; %{ $str += "C:\vcpkg;" } ; setx PATH $str; %{ $str = "" }
打开 PowerShell 并运行:
[Environment]::SetEnvironmentVariable("PATH", "$ENV:PATH;<path to exe>", "USER")
$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")
New-Item env:\$key -Value $value -Force | Out-Null
"
)。 - Nilzor$($Env:PATH).Split(';') | %{ $str += "$($_.Trim('"'));" }; $Env:PATH=$str
- d3r3kksetx.exe
和[Environment]::SetEnvironmentVariable()
的解决方案,因为它们总是将REG_EXPAND_SZ
定义替换为REG_SZ
条目,这意味着动态引用其他环境变量的条目会被转换为静态条目。此外,setx.exe
具有 1024 个字符的硬长度限制。 - mklement0Add-Path
。 - dank8