Vas*_*sil 558 windows powershell
我发现设置PATH环境变量只影响旧的命令提示符.PowerShell似乎有不同的环境设置.如何更改PowerShell(v1)的环境变量?
注意:
我希望永久更改我的更改,因此每次运行PowerShell时都不必设置它.PowerShell有配置文件吗?像Unix上的Bash配置文件?
mlo*_*kot 606
如果,在PowerShell会话期间的某个时间,您需要临时附加到PATH环境变量,您可以这样做:
$env:Path += ";C:\Program Files\GnuWin32\bin"
Run Code Online (Sandbox Code Playgroud)
Jar*_*Par 409
可以使用该env: namespace / drive信息更改实际环境变量.例如,此代码将更新路径环境变量:
$env:Path = "SomeRandomPath"; (replaces existing path)
$env:Path += ";SomeRandomPath" (appends to existing path)
Run Code Online (Sandbox Code Playgroud)
有一些方法可以永久保持环境设置,但如果您只是从PowerShell使用它们,那么使用您的配置文件启动设置可能要好得多.在启动时,PowerShell将运行 它在My Documents文件夹下的WindowsPowerShell目录中找到的任何.ps1文件.通常,您已经有profile.ps1 文件.我的电脑上的路径是
C:\Users\JaredPar\Documents\WindowsPowerShell\profile.ps1
Run Code Online (Sandbox Code Playgroud)
小智 238
您还可以使用以下命令永久修改用户/系统环境变量(即,将在shell重新启动时保持持久性):
[Environment]::SetEnvironmentVariable
("Path", $env:Path, [System.EnvironmentVariableTarget]::Machine)
Run Code Online (Sandbox Code Playgroud)
tjb*_*tjb 57
从PowerShell提示符:
setx PATH "$env:path;\the\directory\to\add" -m
Run Code Online (Sandbox Code Playgroud)
然后你应该看到文字:
SUCCESS: Specified value was saved.
Run Code Online (Sandbox Code Playgroud)
重新启动会话,变量将可用.setx也可以用来设置任意变量.键入setx /?在提示文档.
在以这种方式弄乱路径之前,请确保通过$env:path >> a.out在PowerShell提示符下保存现有路径的副本.
Mic*_*pat 25
就像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 ';'
}
}
Run Code Online (Sandbox Code Playgroud)
查看我的要点以获得相应的Remove-EnvPath功能.
gij*_*ijs 16
虽然当前接受的答案在路径变量从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
Run Code Online (Sandbox Code Playgroud)
有关更多信息,请参阅博客文章使用PowerShell修改您的环境路径
如果使用PowerShell社区扩展,则向环境变量路径添加路径的正确命令是:
Add-PathVariable "C:\NewFolderToAddToTheList" -Target Machine
Run Code Online (Sandbox Code Playgroud)
所有建议永久性更改的答案都有同样的问题:它们打破了路径注册表值.
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
}
Run Code Online (Sandbox Code Playgroud)
我在博客文章中更详细地解释了这个问题.
小智 8
这将设置当前会话的路径并提示用户永久添加它:
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'
}
}
Run Code Online (Sandbox Code Playgroud)
您可以将此功能添加到默认配置文件(Microsoft.PowerShell_profile.ps1),通常位于%USERPROFILE%\Documents\WindowsPowerShell.
小智 8
我的建议是这样的:
我已经对此进行了测试以永久添加C:\oracle\x64\bin到环境变量中,Path并且效果很好。
$ENV:PATH
Run Code Online (Sandbox Code Playgroud)
第一种方法很简单:
$ENV:PATH=”$ENV:PATH;c:\path\to\folder”
Run Code Online (Sandbox Code Playgroud)
但这种变化不是永久性的。$env:path一旦您关闭 PowerShell 终端并再次重新打开它,它将默认恢复到之前的状态。那是因为您已在会话级别而不是在源级别(即注册表级别)应用更改。要查看 的全局值$env:path,请执行以下操作:
Get-ItemProperty -Path ‘Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment’ -Name PATH
Run Code Online (Sandbox Code Playgroud)
或者更具体地说:
(Get-ItemProperty -Path ‘Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment’ -Name PATH).path
Run Code Online (Sandbox Code Playgroud)
现在要改变这个,首先我们捕获需要修改的原始路径:
$oldpath = (Get-ItemProperty -Path ‘Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment’ -Name PATH).path
Run Code Online (Sandbox Code Playgroud)
现在我们定义新路径应该是什么样子。在这种情况下,我们将附加一个新文件夹:
$newpath = “$oldpath;c:\path\to\folder”
Run Code Online (Sandbox Code Playgroud)
注意:确保$newpath看起来像你想要的样子。如果没有,那么您可能会损坏您的操作系统。
现在应用新值:
Set-ItemProperty -Path ‘Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment’ -Name PATH -Value $newPath
Run Code Online (Sandbox Code Playgroud)
现在做最后的检查,它看起来像你期望的那样:
(Get-ItemProperty -Path ‘Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment’ -Name PATH).Path
Run Code Online (Sandbox Code Playgroud)
您现在可以重新启动 PowerShell 终端(甚至重新启动机器),并看到它不会再次回滚到其旧值。
请注意,路径的顺序可能会发生变化,因此按字母顺序排列,因此请确保检查整行。为方便起见,您可以使用分号作为分隔符将输出拆分为多行:
($env:path).split(“;”)
Run Code Online (Sandbox Code Playgroud)
只有将值推入注册表的答案才会影响永久更改(因此该线程上的大多数答案,包括接受的答案,不会永久影响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"
Run Code Online (Sandbox Code Playgroud)
在@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 ';'
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
在 PowerShell 中,可以通过键入以下内容导航到环境变量目录:
Set-Location Env:
Run Code Online (Sandbox Code Playgroud)
这将带您进入 Env:> 目录。从这个目录中:
要查看所有环境变量,请键入:
Env:\> Get-ChildItem
Run Code Online (Sandbox Code Playgroud)
要查看特定的环境变量,请键入:
Env:\> $Env:<variable name>, e.g. $Env:Path
Run Code Online (Sandbox Code Playgroud)
要设置环境变量,请键入:
Env:\> $Env:<variable name> = "<new-value>", e.g. $Env:Path="C:\Users\"
Run Code Online (Sandbox Code Playgroud)
要删除环境变量,请键入:
Env:\> remove-item Env:<variable name>, e.g. remove-item Env:SECRET_KEY
Run Code Online (Sandbox Code Playgroud)
更多信息在关于环境变量中。
大多数答案都没有解决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
Run Code Online (Sandbox Code Playgroud)
然后用 Invoke-Elevated
Invoke-Elevated {Add-PathVariable $args[0] -Target Machine} -ArgumentList $MY_NEW_DIR
Run Code Online (Sandbox Code Playgroud)
正如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
}
}
Run Code Online (Sandbox Code Playgroud)
不要让自己头疼,想要一个简单的单行解决方案来添加永久环境变量(在提升模式下打开 powershell ):
[Environment]::SetEnvironmentVariable("NewEnvVar", "NewEnvValue", "Machine")
Run Code Online (Sandbox Code Playgroud)
关闭会话并再次打开它以完成任务
如果您想修改/更改:
[Environment]::SetEnvironmentVariable("oldEnvVar", "NewEnvValue", "Machine")
Run Code Online (Sandbox Code Playgroud)
如果你想删除/删除:
[Environment]::SetEnvironmentVariable("oldEnvVar", "", "Machine")
Run Code Online (Sandbox Code Playgroud)
需要说明的是,1990年代的Windows方式是点击开始,右键点击This PC,选择属性,然后选择高级系统设置,然后在弹出的对话框中选择环境变量,在列表中双击在PATH 上,然后使用New、Edit、Move Up和Move Down仍然可以更改 PATH。Power shell 和 Windows 的其余部分获得您在此处设置的任何内容。
是的,您可以使用这些新方法,但旧方法仍然有效。在基本级别,所有永久更改方法都是编辑注册表文件的受控方式。
| 归档时间: |
|
| 查看次数: |
562858 次 |
| 最近记录: |