设置 Windows PowerShell 环境变量
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/714877/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Setting Windows PowerShell environment variables
提问by Vasil
I have found out that setting the PATH environment variable affects only the old command prompt. PowerShell seems to have different environment settings. How do I change the environment variables for PowerShell (v1)?
我发现设置 PATH 环境变量只会影响旧的命令提示符。PowerShell 似乎有不同的环境设置。如何更改 PowerShell (v1) 的环境变量?
Note:
笔记:
I want to make my changes permanent, so I don't have to set it every time I run PowerShell. Does PowerShell have a profile file? Something like Bash profile on Unix?
我想让我的更改永久化,所以我不必每次运行 PowerShell 时都设置它。PowerShell 有配置文件吗?类似于 Unix 上的 Bash 配置文件?
采纳答案by JaredPar
Changing the actual environment variables can be done by
using the env: namespace / drive
information. For example, this
code will update the path environment variable:
可以通过使用这些env: namespace / drive
信息来更改实际的环境变量。例如,此代码将更新路径环境变量:
$env:Path = "SomeRandomPath"; (replaces existing path)
$env:Path += ";SomeRandomPath" (appends to existing path)
There are ways to make environment settings permanent, but
if you are only using them from PowerShell, it's probably
a lot better to use your profile to initiate the
settings. On startup, PowerShell will run any .ps1files it finds in the WindowsPowerShell
directory under
My Documents folder. Typically you have a profile.ps1file already there. The path on my computer is
有多种方法可以使环境设置永久化,但如果您仅从 PowerShell 使用它们,那么使用您的配置文件来启动设置可能会好得多。启动时,PowerShell 将运行
它在“我的文档”文件夹下的目录中找到的任何.ps1文件WindowsPowerShell
。通常,您已经有一个profile.ps1文件。我电脑上的路径是
C:\Users\JaredPar\Documents\WindowsPowerShell\profile.ps1
回答by mloskot
If, some time during a PowerShell session, you need to append to the PATH environment variable temporarily, you can do it this way:
如果在 PowerShell 会话期间的某个时间,您需要临时附加到 PATH 环境变量,您可以这样做:
$env:Path += ";C:\Program Files\GnuWin32\bin"
回答by hoge
You can also modify user/system environment variables permanently(i.e. will be persistent across shell restarts) with the following:
您还可以使用以下命令永久修改用户/系统环境变量(即在 shell 重启后将保持不变):
Modify a system environment variable
修改系统环境变量
[Environment]::SetEnvironmentVariable
("Path", $env:Path, [System.EnvironmentVariableTarget]::Machine)
Modify a user environment variable
修改用户环境变量
[Environment]::SetEnvironmentVariable
("INCLUDE", $env:INCLUDE, [System.EnvironmentVariableTarget]::User)
Usage from comments - add to the system environment variable
注释中的用法 - 添加到系统环境变量中
[Environment]::SetEnvironmentVariable(
"Path",
[Environment]::GetEnvironmentVariable("Path", [EnvironmentVariableTarget]::Machine) + ";C:\bin",
[EnvironmentVariableTarget]::Machine)
String based solution is also possible if you don't want to write types
如果您不想编写类型,也可以使用基于字符串的解决方案
[Environment]::SetEnvironmentVariable("Path", $env:Path + ";C:\bin", "Machine")
回答by tjb
From the PowerShell prompt:
从 PowerShell 提示符:
setx PATH "$env:path;\the\directory\to\add" -m
You should then see the text:
然后你应该看到文本:
SUCCESS: Specified value was saved.
Restart your session, and the variable will be available. setx
can also be used to set arbitrary variables. Type setx /?
at the prompt for documentation.
重新启动会话,变量将可用。setx
也可用于设置任意变量。setx /?
在文档提示下键入。
Before messing with your path in this way, make sure that you save a copy of your existing path by doing $env:path >> a.out
in a PowerShell prompt.
在以这种方式弄乱您的路径之前,请确保通过$env:path >> a.out
在 PowerShell 提示符中执行操作来保存现有路径的副本。
回答by Michael Kropat
Like JeanT's answer, I wanted an abstraction around adding to the path. Unlike JeanT's answer I needed it to run without user interaction. Other behavior I was looking for:
就像JeanT 的回答一样,我想要一个关于添加到路径的抽象。与 JeanT 的回答不同,我需要它在没有用户交互的情况下运行。我正在寻找的其他行为:
- Updates
$env:Path
so the change takes effect in the current session - Persists the environment variable change for future sessions
- Doesn't add a duplicate path when the same path already exists
- 更新
$env:Path
以使更改在当前会话中生效 - 为将来的会话保留环境变量更改
- 当相同的路径已经存在时不添加重复的路径
In case it's useful, here it is:
如果它有用,这里是:
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 ';'
}
}
Check out my gistfor the corresponding Remove-EnvPath
function.
查看我的要点以了解相应的Remove-EnvPath
功能。
回答by gijswijs
Although the current accepted answer works in the sense that the path variable gets permanently updated from the context of PowerShell, it doesn't actually update the environment variable stored in the Windows registry.
尽管当前接受的答案在路径变量从 PowerShell 的上下文中永久更新的意义上起作用,但它实际上并没有更新存储在 Windows 注册表中的环境变量。
To achieve that, you can obviously use PowerShell as well:
为此,您显然也可以使用 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
More information is in blog post Use PowerShell to Modify Your Environmental Path
更多信息在博客文章使用 PowerShell 修改您的环境路径中
If you use PowerShell community extensions, the proper command to add a path to the environment variable path is:
如果您使用 PowerShell 社区扩展,则向环境变量路径添加路径的正确命令是:
Add-PathVariable "C:\NewFolderToAddToTheList" -Target Machine
回答by Peter Hahndorf
All the answers suggesting a permanent change have the same problem: They break the path registry value.
所有建议永久更改的答案都有相同的问题:它们破坏了路径注册表值。
SetEnvironmentVariable
turns the REG_EXPAND_SZ
value %SystemRoot%\system32
into a REG_SZ
value of C:\Windows\system32
.
SetEnvironmentVariable
将REG_EXPAND_SZ
值%SystemRoot%\system32
转换为 的REG_SZ
值C:\Windows\system32
。
Any other variables in the path are lost as well. Adding new ones using %myNewPath%
won't work any more.
路径中的任何其他变量也会丢失。添加新的使用%myNewPath%
将不再起作用。
Here's a script Set-PathVariable.ps1
that I use to address this problem:
这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
}
I explain the problem in more detail in a blog post.
我在博客文章中更详细地解释了这个问题。
回答by JeanT
This sets the path for the current session and prompts the user to add it permanently:
这将设置当前会话的路径并提示用户永久添加它:
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'
}
}
You can add this function to your default profile, (Microsoft.PowerShell_profile.ps1
), usually located at %USERPROFILE%\Documents\WindowsPowerShell
.
您可以将此功能添加到您的默认配置文件 ( Microsoft.PowerShell_profile.ps1
),通常位于%USERPROFILE%\Documents\WindowsPowerShell
。
回答by SBF
Building on @Michael Kropat'sanswer I added a parameter to prepend the new path to the existing PATH
variable and a check to avoid the addition of a non-existing path:
以@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 ';'
}
}
}
}
回答by Jonathan
Most answers aren't addressing UAC. This covers UAC issues.
大多数答案都没有针对UAC。这涵盖了 UAC 问题。
First install PowerShell Community Extensions: choco install pscx
via http://chocolatey.org/(you may have to restart your shell environment).
首先安装 PowerShell 社区扩展:choco install pscx
通过http://chocolatey.org/(您可能需要重新启动 shell 环境)。
Then enable pscx
然后启用pscx
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser #allows scripts to run from the interwebs, such as pcsx
Then use Invoke-Elevated
然后使用 Invoke-Elevated
Invoke-Elevated {Add-PathVariable $args[0] -Target Machine} -ArgumentList $MY_NEW_DIR