我发现,设置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会运行在 "WindowsPowerShell "中找到的任何.ps1文件。 文件,这些文件在 "我的文档 "文件夹下的 "WindowsPowerShell "目录中找到。 我的文档目录下的任何.ps1文件。一般来说,你有一个profile.ps1 文件已经在那里了。我的电脑上的路径是
C:\Users\JaredPar\Documents\WindowsPowerShell\profile.ps1
你也可以用以下方法**永久地修改用户/系统环境变量(即在重新启动shell时也会持续存在)。
修改一个系统环境变量
[Environment]::SetEnvironmentVariable ("Path", $env:Path, [System.EnvironmentVariableTarget]::Machine)
修改一个用户环境变量
[Environment]::SetEnvironmentVariable ("INCLUDE", $env:INCLUDE, [System.EnvironmentVariableTarget]::User)
评论中的用法--添加到系统环境变量中
[Environment]::SetEnvironmentVariable( "Path", [Environment]::GetEnvironmentVariable("Path", [EnvironmentVariableTarget]::Machine) + ";C:\bin", [EnvironmentVariableTarget]::Machine)
如果你不想写类型,也可以采用基于字符串的解决方案
[Environment]::SetEnvironmentVariable("Path", $env:Path + ";C:\bin", "Machine")
从PowerShell提示中。
setx PATH "$env:path;\the\directory\to\add" -m
然后你就应该看到这段文字。
SUCCESS: Specified value was saved.
重新启动你的会话,这个变量就可以使用了。 setx也可以用来设置任意变量。 在提示符下键入setx /?以获取文档。
setx
setx /?
在以这种方式对路径进行修改之前,请确保你通过在PowerSeries中执行$env:path >>.a.out来保存现有路径的副本。 a.out`在PowerShell提示下保存一份现有路径。
$env:path >>.a.out
和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函数。
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修改环境路径][1]。
如果你使用PowerShell社区扩展,向环境变量路径添加路径的正确命令是:
Add-PathVariable "C:\NewFolderToAddToTheList" -Target Machine
。
[1]: http://blogs.technet.com/b/heyscriptingguy/archive/2011/07/23/use-powershell-to-modify-your-environmental-path.aspx
所有建议永久更改的答案都有同样的问题。 它们破坏了路径注册表的值。
SetEnvironmentVariable将REG_EXPAND_SZ值%SystemRoot%/system32变成REG_SZ值C:/Windows/system32`。
SetEnvironmentVariable
REG_EXPAND_SZ
%SystemRoot%/system32
REG_SZ
C:
路径中的其他变量也会丢失。 使用%myNewPath%添加新的变量将无法工作。
%myNewPath%
下面是我用来解决这个问题的脚本Set-PathVariable.ps1。
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 }
我在一篇博客文章中更详细地解释了这个问题。
1:
这将设置当前会话的路径,并提示用户永久添加。
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' } }
你可以把这个函数添加到你的默认配置文件中,(微软.PowerShell_profile.ps1),通常位于%USERPROFILE%Documents/WindowsPowerShell。
微软.PowerShell_profile.ps1
%USERPROFILE%Documents/WindowsPowerShell
在 [@Michael Kropat's][1] 答案的基础上,我添加了一个参数,用于将新的路径预置到现有的 PATH变量中,并添加了一个检查,以避免添加一个不存在的路径。
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 ';' } } } }
[1]: https://stackoverflow.com/a/34844707/1509300 "Michael Kropat"。
正如 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 } }
大多数答案都没有解决【UAC】[1]。 这涵盖了UAC问题。
首先安装PowerShell社区扩展。 choco install pscx通过http://chocolatey.org/ (你可能需要重新启动你的shell环境)。
choco install pscx
然后启用pscx
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser #allows scripts to run from the interwebs, such as pcsx
然后使用 "Invok-Elevated"。
Invoke-Elevated {Add-PathVariable $args[0] -Target Machine} -ArgumentList $MY_NEW_DIR
[1]: http://en.wikipedia.org/wiki/User_Account_Control
打开PowerShell并运行。
[Environment]::SetEnvironmentVariable("PATH", "$ENV:PATH;<path to exe>", "USER")
我的建议是这个。
我测试了一下,把C:\oracle\x64bin永久地添加到环境变量Path中,这样就可以了。
C:\oracle\x64bin
Path
$ENV:PATH
第一个方法就是简单的做。
$ENV:PATH=”$ENV:PATH;c:\path\to\folder”
但这种改变并不是永久性的。 当你关闭PowerShell终端并重新打开时,$env:path将默认恢复到之前的状态。 这是因为你在会话级别而不是在源代码级别(即注册表级别)应用了更改。 要查看$env:path的全局值,可以这样做。
$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看起来是你想要的样子。 请确保$newpath看起来是你想要的样子。 如果不是,那么你可能会损坏你的操作系统。
$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(“;”)
我试图优化SBF's和[Michael's][2]的代码,使其更加紧凑。
我依靠PowerShell'的类型强制,它自动将字符串转换为枚举值,所以我没有定义查找字典。
我还调出了根据条件将新路径添加到列表中的块,这样工作就完成了一次,并存储在一个变量中以便重复使用。
然后根据$PathContainer参数的不同,永久应用或只应用于Session。
$PathContainer
我们可以把代码块放在一个函数或ps1文件中,直接从命令提示符中调用。 我选择了DevEnvAddPath.ps1。
param( [Parameter(Position=0,Mandatory=$true)][String]$PathChange, [ValidateSet('Machine', 'User', 'Session')] [Parameter(Position=1,Mandatory=$false)][String]$PathContainer='Session', [Parameter(Position=2,Mandatory=$false)][Boolean]$PathPrepend=$false ) [String]$ConstructedEnvPath = switch ($PathContainer) { "Session"{${env:Path};} default{[Environment]::GetEnvironmentVariable('Path', $containerType);} }; $PathPersisted = $ConstructedEnvPath -split ';'; if ($PathPersisted -notcontains $PathChange) { $PathPersisted = $(switch ($PathPrepend) { $true{,$PathChange + $PathPersisted;} default{$PathPersisted + $PathChange;} }) | Where-Object { $_ }; $ConstructedEnvPath = $PathPersisted -join ";"; } if ($PathContainer -ne 'Session') { # Save permanently to Machine, User [Environment]::SetEnvironmentVariable("Path", $ConstructedEnvPath, $PathContainer); } # Update the current session ${env:Path} = $ConstructedEnvPath;
我为DevEnvRemovePath.ps1做了类似的事情。
param( [Parameter(Position=0,Mandatory=$true)][String]$PathChange, [ValidateSet('Machine', 'User', 'Session')] [Parameter(Position=1,Mandatory=$false)][String]$PathContainer='Session' ) [String]$ConstructedEnvPath = switch ($PathContainer) { "Session"{${env:Path};} default{[Environment]::GetEnvironmentVariable('Path', $containerType);} }; $PathPersisted = $ConstructedEnvPath -split ';'; if ($PathPersisted -contains $PathChange) { $PathPersisted = $PathPersisted | Where-Object { $_ -ne $PathChange }; $ConstructedEnvPath = $PathPersisted -join ";"; } if ($PathContainer -ne 'Session') { # Save permanently to Machine, User [Environment]::SetEnvironmentVariable("Path", $ConstructedEnvPath, $PathContainer); } # Update the current session ${env:Path} = $ConstructedEnvPath;
到目前为止,它们似乎是有效的。
[2]: https://stackoverflow.com/questions/714877/setting-windows-powershell-environment-variables/34844707#34844707
在PowerShell中,可以通过键入来导航到环境变量目录。
Set-Location Env:
这将使你进入Env:> 目录。 在这个目录中。
要查看所有环境变量,键入:
Env:\> Get-ChildItem
要查看特定的环境变量,请键入:
Env:\> $Env:, e.g. $Env:Path
要设置一个环境变量,请键入:{{{5630585}}。
Env:\> $Env: = "", e.g. $Env:Path="C:\Users\"
要删除一个环境变量,请输入。
Env:\> remove-item Env:, e.g. remove-item Env:SECRET_KEY
更多信息请参见关于环境变量。
如果在PowerShell会话中的某个时候,你需要 暂时追加到PATH环境变量中,你可以这样做 这样做。
改变实际的环境变量可以通过以下方式完成 使用 "env: namespace / drive "信息。例如,这个 代码将更新路径环境变量。
有一些方法可以使环境设置永久化,但是 如果你只在PowerShell中使用这些设置,那么使用你的配置文件来启动这些设置可能会好得多。 使用你的配置文件来启动这些 设置。在启动时,PowerShell会运行在 "WindowsPowerShell "中找到的任何.ps1文件。 文件,这些文件在 "我的文档 "文件夹下的 "WindowsPowerShell "目录中找到。 我的文档目录下的任何.ps1文件。一般来说,你有一个profile.ps1 文件已经在那里了。我的电脑上的路径是
你也可以用以下方法**永久地修改用户/系统环境变量(即在重新启动shell时也会持续存在)。
修改一个系统环境变量
修改一个用户环境变量
评论中的用法--添加到系统环境变量中
如果你不想写类型,也可以采用基于字符串的解决方案
从PowerShell提示中。
然后你就应该看到这段文字。
重新启动你的会话,这个变量就可以使用了。
setx
也可以用来设置任意变量。 在提示符下键入setx /?
以获取文档。在以这种方式对路径进行修改之前,请确保你通过在PowerSeries中执行
$env:path >>.a.out
来保存现有路径的副本。 a.out`在PowerShell提示下保存一份现有路径。和JeanT'的回答一样,我想要一个围绕添加到路径的抽象。 与JeanT'的回答不同,我需要它在没有用户交互的情况下运行。 我正在寻找的其他行为。
$env:Path
,使更改在当前会话中生效。万一有用的话,就在这里。
查看我的要旨,查看相应的
Remove-EnvPath
函数。虽然目前公认的答案是在PowerShell的上下文中永久更新路径变量,但它实际上并没有更新存储在Windows注册表中的环境变量。
要实现这一点,你显然也可以使用PowerShell。
更多信息请参见博客文章[使用PowerShell修改环境路径][1]。
如果你使用PowerShell社区扩展,向环境变量路径添加路径的正确命令是:
。
[1]: http://blogs.technet.com/b/heyscriptingguy/archive/2011/07/23/use-powershell-to-modify-your-environmental-path.aspx
所有建议永久更改的答案都有同样的问题。 它们破坏了路径注册表的值。
SetEnvironmentVariable
将REG_EXPAND_SZ
值%SystemRoot%/system32
变成REG_SZ
值C:
/Windows/system32`。路径中的其他变量也会丢失。 使用
%myNewPath%
添加新的变量将无法工作。下面是我用来解决这个问题的脚本
Set-PathVariable.ps1
。我在一篇博客文章中更详细地解释了这个问题。
1:
这将设置当前会话的路径,并提示用户永久添加。
你可以把这个函数添加到你的默认配置文件中,(
微软.PowerShell_profile.ps1
),通常位于%USERPROFILE%Documents/WindowsPowerShell
。在 [@Michael Kropat's][1] 答案的基础上,我添加了一个参数,用于将新的路径预置到现有的
PATH
变量中,并添加了一个检查,以避免添加一个不存在的路径。[1]: https://stackoverflow.com/a/34844707/1509300 "Michael Kropat"。
正如 Jonathan Leaders 提到的 这里,要想为'机'更改环境变量,必须将命令/脚本升高运行,但有些命令的升高运行并不一定要通过社区扩展来完成,所以我想修改并扩展 JeanT'的 答案,即使脚本本身没有升高运行,也可以更改机器变量。
大多数答案都没有解决【UAC】[1]。 这涵盖了UAC问题。
首先安装PowerShell社区扩展。
choco install pscx
通过http://chocolatey.org/ (你可能需要重新启动你的shell环境)。然后启用pscx
然后使用 "Invok-Elevated"。
[1]: http://en.wikipedia.org/wiki/User_Account_Control
打开PowerShell并运行。
我的建议是这个。
我测试了一下,把
C:\oracle\x64bin
永久地添加到环境变量Path
中,这样就可以了。第一个方法就是简单的做。
但这种改变并不是永久性的。 当你关闭PowerShell终端并重新打开时,
$env:path
将默认恢复到之前的状态。 这是因为你在会话级别而不是在源代码级别(即注册表级别)应用了更改。 要查看$env:path
的全局值,可以这样做。或者更具体地说。
现在要改,首先我们捕捉需要修改的原始路径。
现在我们定义新路径的样子。 在本例中,我们将添加一个新的文件夹。
注意:要确保
$newpath
看起来是你想要的样子。 请确保$newpath
看起来是你想要的样子。 如果不是,那么你可能会损坏你的操作系统。现在应用新的值。
现在做最后一次检查,看看它是否符合你的期望。
现在你可以重启PowerShell终端(甚至重启机器),看看它是不是又回到了它的旧值。
请注意,路径的顺序可能会改变,所以它是按字母顺序排列的,所以请确保你检查整行。 为了方便起见,你可以使用分号作为分隔符,将输出结果分成几行。
我试图优化SBF's和[Michael's][2]的代码,使其更加紧凑。
我依靠PowerShell'的类型强制,它自动将字符串转换为枚举值,所以我没有定义查找字典。
我还调出了根据条件将新路径添加到列表中的块,这样工作就完成了一次,并存储在一个变量中以便重复使用。
然后根据
$PathContainer
参数的不同,永久应用或只应用于Session。我们可以把代码块放在一个函数或ps1文件中,直接从命令提示符中调用。 我选择了DevEnvAddPath.ps1。
我为DevEnvRemovePath.ps1做了类似的事情。
到目前为止,它们似乎是有效的。
1:
[2]: https://stackoverflow.com/questions/714877/setting-windows-powershell-environment-variables/34844707#34844707
在PowerShell中,可以通过键入来导航到环境变量目录。
这将使你进入Env:> 目录。 在这个目录中。
要查看所有环境变量,键入:
要查看特定的环境变量,请键入:
。
要设置一个环境变量,请键入:{{{5630585}}。
要删除一个环境变量,请输入。
更多信息请参见关于环境变量。
1: