我发现设置PATH环境变量只影响旧的命令提示符.PowerShell似乎有不同的环境设置.如何更改PowerShell(v1)的环境变量?
注意:
我希望永久更改我的更改,因此每次运行PowerShell时都不必设置它.PowerShell有配置文件吗?像Unix上的Bash配置文件?
如果,在PowerShell会话期间的某个时间,您需要临时附加到PATH环境变量,您可以这样做:
$env:Path += ";C:\Program Files\GnuWin32\bin"
可以使用该env: namespace / drive
信息更改实际环境变量.例如,此代码将更新路径环境变量:
$env:Path = "SomeRandomPath"; (replaces existing path)
$env:Path += ";SomeRandomPath" (appends to existing path)
有一些方法可以永久保持环境设置,但如果您只是从PowerShell使用它们,那么使用您的配置文件启动设置可能要好得多.在启动时,PowerShell将运行 它在My Documents文件夹下的WindowsPowerShell目录中找到的任何.ps1文件.通常,您已经有profile.ps1 文件.我的电脑上的路径是
C:\Users\JaredPar\Documents\WindowsPowerShell\profile.ps1
您还可以使用以下命令永久修改用户/系统环境变量(即,将在shell重新启动时保持持久性):
[Environment]::SetEnvironmentVariable ("Path", $env:Path, [System.EnvironmentVariableTarget]::Machine)
从PowerShell提示符:
setx PATH "$env:path;\the\directory\to\add" -m
然后你应该看到文字:
SUCCESS: Specified value was saved.
重新启动会话,变量将可用.setx
也可以用来设置任意变量.键入setx /?
在提示文档.
在以这种方式弄乱路径之前,请确保通过$env:path >> a.out
在PowerShell提示符下保存现有路径的副本.
就像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
功能.
虽然当前接受的答案在路径变量从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社区扩展,则向环境变量路径添加路径的正确命令是:
Add-PathVariable "C:\NewFolderToAddToTheList" -Target Machine
所有建议永久性更改的答案都有同样的问题:它们打破了路径注册表值.
SetEnvironmentVariable
将REG_EXPAND_SZ
值%SystemRoot%\system32
转换为REG_SZ
值C:\Windows\system32
.
路径中的任何其他变量也会丢失.添加新的使用%myNewPath%
将不再起作用.
这Set-PathVariable.ps1
是我用来解决这个问题的脚本:
[CmdletBinding(SupportsShouldProcess=$true)] param( [parameter(Mandatory=$true)] [string]$NewLocation) Begin { #requires –runasadministrator $regPath = "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" $hklm = [Microsoft.Win32.Registry]::LocalMachine Function GetOldPath() { $regKey = $hklm.OpenSubKey($regPath, $FALSE) $envpath = $regKey.GetValue("Path", "", [Microsoft.Win32.RegistryValueOptions]::DoNotExpandEnvironmentNames) return $envPath } } Process { # Win32API error codes $ERROR_SUCCESS = 0 $ERROR_DUP_NAME = 34 $ERROR_INVALID_DATA = 13 $NewLocation = $NewLocation.Trim(); If ($NewLocation -eq "" -or $NewLocation -eq $null) { Exit $ERROR_INVALID_DATA } [string]$oldPath = GetOldPath Write-Verbose "Old Path: $oldPath" # Check whether the new location is already in the path $parts = $oldPath.split(";") If ($parts -contains $NewLocation) { Write-Warning "The new location is already in the path" Exit $ERROR_DUP_NAME } # Build the new path, make sure we don't have double semicolons $newPath = $oldPath + ";" + $NewLocation $newPath = $newPath -replace ";;","" if ($pscmdlet.ShouldProcess("%Path%", "Add $NewLocation")){ # Add to the current session $env:path += ";$NewLocation" # Save into registry $regKey = $hklm.OpenSubKey($regPath, $True) $regKey.SetValue("Path", $newPath, [Microsoft.Win32.RegistryValueKind]::ExpandString) Write-Output "The operation completed successfully." } Exit $ERROR_SUCCESS }
我在博客文章中更详细地解释了这个问题.
这将设置当前会话的路径并提示用户永久添加它:
function Set-Path { param([string]$x) $Env:Path+= ";" + $x Write-Output $Env:Path $write = Read-Host 'Set PATH permanently ? (yes|no)' if ($write -eq "yes") { [Environment]::SetEnvironmentVariable("Path",$env:Path, [System.EnvironmentVariableTarget]::User) Write-Output 'PATH updated' } }
您可以将此功能添加到默认配置文件(Microsoft.PowerShell_profile.ps1
),通常位于%USERPROFILE%\Documents\WindowsPowerShell
.
在@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 ';' } } } }
大多数答案都没有解决UAC问题.这涵盖了UAC问题.
首先安装PowerShell社区扩展:choco install pscx
通过http://chocolatey.org/(您可能必须重新启动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
正如Jonathan Leaders在此提到的那样,重要的是运行命令/脚本以提升能够更改"机器"的环境变量,但运行一些提升的命令不一定要使用社区扩展,所以我想要以某种方式修改和扩展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
}
}