设置Windows PowerShellpathvariables
我发现设置PATH环境variables只影响旧命令提示符。 PowerShell似乎有不同的环境设置。 如何更改PowerShell(v1)的环境variables?
注意:
我想使我的更改永久化,所以我不必每次运行PowerShell时都进行设置。 PowerShell有一个configuration文件? 像Unix上的Bashconfiguration文件?
更改实际的环境variables可以使用env: namespace / drive
信息来完成。 例如,这段代码将更新path环境variables:
$env:Path = "SomeRandomPath";
有一些方法可以使环境设置成为永久的,但是如果你只是从PowerShell中使用它们,那么使用你的configuration文件来启动设置可能会好很多。 启动时,PowerShell将运行在“我的文档”文件夹下的WindowsPowerShell目录中find的任何.ps1文件。 通常你已经有一个profile.ps1文件。 我的电脑上的path是
c:\Users\JaredPar\Documents\WindowsPowerShell\profile.ps1
如果在PowerShell会话的某段时间,您需要暂时修改PATH环境variables,您可以这样做:
$env:Path += ";C:\Program Files\GnuWin32\bin"
您还可以使用以下方式永久修改用户/系统环境variables(即在整个shell重启过程中持久化)
### Modify system environment variable ### [Environment]::SetEnvironmentVariable ( "Path", $env:Path, [System.EnvironmentVariableTarget]::Machine ) ### Modify user environment variable ### [Environment]::SetEnvironmentVariable ( "INCLUDE", $env:INCLUDE, [System.EnvironmentVariableTarget]::User ) ### from comments ### ### Usage from comments - Add to the system environment variable ### [Environment]::SetEnvironmentVariable("Path", $env:Path + ";C:\bin", [EnvironmentVariableTarget]::Machine)
在PowerShell提示符下:
setx PATH "$env:path;\the\directory\to\add" -m
你应该看到文字:
SUCCESS: Specified value was saved.
重新启动你的会话,variables将可用。 setx
也可以用来设置任意variables。 键入setx /?
在提示文件。
在以这种方式处理path之前,请确保通过在PowerShell提示符中执行$env:path >> a.out
来保存现有path的副本。
虽然当前接受的答案的工作原理是pathvariables从PowerShell的上下文中永久更新,但它实际上并不更新存储在Windowsregistry中的环境variables。 为了达到这个目的,你显然也可以使用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
这里有更多的信息: http : //blogs.technet.com/b/heyscriptingguy/archive/2011/07/23/use-powershell-to-modify-your-environmental-path.aspx
如果您使用PowerShell社区扩展,则向环境variablespath添加path的正确命令是:
Add-PathVariable "C:\NewFolderToAddToTheList" -Target Machine
像JeanT的回答 ,我想要一个抽象的道路添加。 与JeanT的答案不同,我需要它在没有用户交互的情况下运行。 我正在寻找的其他行为:
- 更新
$env:Path
以便更改在当前会话中生效 - 坚持未来会议环境variables的变化
- 当相同path已经存在时不添加重复的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
function。
这将设置当前会话的path并提示用户永久添加它:
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' } }
您可以将此函数添加到您的默认configuration文件( Microsoft.PowerShell_profile.ps1
),通常位于%USERPROFILE%\Documents\WindowsPowerShell
。
正如Jonathan Leaders在这里提到的那样,运行提升的命令/脚本来改变'machine'的环境variables是很重要的 ,但是运行一些提升的命令并不需要使用Community Extensions来完成,所以我想以某种方式修改和扩展JeanT的 答案 ,即使脚本本身没有运行,也可以执行改变的机器variables:
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 } }
所有build议永久性更改的答案都有相同的问题:它们会破坏pathregistry值。
SetEnvironmentVariable
将REG_EXPAND_SZ
值%SystemRoot%\system32
转换为C:\Windows\system32
的REG_SZ
值。
path中的其他variables也会丢失。 使用%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 }
我在博客文章中更详细地解释了这个问题。
大多数答案都没有解决UAC问题 。 这涵盖了UAC问题。
首先安装PowerShell社区扩展:通过http://chocolatey.org/ 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