【问题标题】:Not able to set multiple path variable using powershell无法使用 powershell 设置多个路径变量
【发布时间】:2020-02-25 12:49:48
【问题描述】:

我正在尝试使用 PowerShell 设置多个路径变量,但只附加了最后一个。

[Environment]::SetEnvironmentVariable('JAVA_HOME', 'C:\Program Files\Java\jdk-13.0.2', 'User')
[Environment]::SetEnvironmentVariable('JAVA_HOME', 'C:\Program Files\Java\jdk-13.0.2', 'Machine')
[Environment]::SetEnvironmentVariable("Path", $env:Path + ";C:\Program Files\Java\jdk-13.0.2\bin", "User")
[Environment]::SetEnvironmentVariable("Path", $env:Path + ";C:\Program Files\Java\jdk-13.0.2\bin", "Machine")
[Environment]::SetEnvironmentVariable("Path", $env:Path + ";C:\Windows\System32", "User")
[Environment]::SetEnvironmentVariable("Path", $env:Path + ";C:\Windows\System32", "Machine")
[Environment]::SetEnvironmentVariable("Path", $env:Path + ";C:\apache-jmeter-5.2.1\bin", "User")
[Environment]::SetEnvironmentVariable("Path", $env:Path + ";C:\apache-jmeter-5.2.1\bin", "Machine")

“JAVA_HOME”创建成功。 但在路径中只附加了最后一个,即 'C:\apache-jmeter-5.2.1\bin'

【问题讨论】:

  • 使用[environment]::GetEnvironmentVariable('Path') 而不是$env:Path

标签: powershell environment-variables azure-virtual-machine


【解决方案1】:

这个脚本存在三个问题:

  1. 当您将[Environment]::SetEnvironmentVariable 用于Process 以外的任何范围时,它不会更新当前进程的环境

如果你想永久设置它并且影响当前进程,你需要调用它两次。

  1. 您正在使用相同的值更新用户机器范围

在 Windows 上,默认进程环境变量是通过在默认机器环境之上分层默认用户环境来构建的。因此,一方面,在两个范围内将相同的 JAVA_HOME 设置为相同的值是冗余

  1. 您正在根据流程中的组合值更新默认 PATH

路径变量是特殊的。过程值是用户和机器环境的组合。因此,仅在其他环境变量中多余的内容可能会导致 PATH 变量出现真正的问题,因为将文件夹添加到这两个值会导致它在您的进程环境路径中出现两个副本。

因此,您永远不应将用户范围机器范围设置为进程中的值,但尤其不应同时设置它们。

例如:

  • 如果用户值只是“C:\Users\Jaykul\Documents\PowerShell\Scripts”
  • 机器值只是“C:\Windows\System32”
  • 该进程将获得“C:\Windows\System32;C:\Users\Jaykul\Documents\PowerShell\Scripts”

如果您接受它,并在其上附加一些内容,然后将其设置回 both,那么您将在新 PATH 中获得 所有内容中的两个你开始一个新的进程。

正确的做法是:

  1. 只修改一个范围(机器范围,用户范围)。
  2. 根据您要更新的内容进行更新。
  3. 同时更新流程范围,以便您了解发生了什么。

我有一个“环境”模块,它位于 PowerShell 库 and github 上,它有一个 Add-Path 函数,可以完成所有这些工作,但基础是:

function Add-Path {
  param($Path, [ValidateSet("User","Machine")]$Scope)

  # Update what we were asked to update
  [Environment]::SetEnvironmentVariable("Path",
    ([Environment]::GetEnvironmentVariable("Path", $Scope) + [IO.Path]::PathSeparator + $Path),
    $Scope)

  # Also update the process scope
  [Environment]::SetEnvironmentVariable("Path",
    ([Environment]::GetEnvironmentVariable("Path", "Process") +  [IO.Path]::PathSeparator + $Path),
    "Process")
}

当然,我链接到的模块中的功能不仅仅如此,确保没有欺骗,并确保将新路径插入到正确位置的进程中(即用户范围之前的机器范围),但这是基础......

【讨论】:

  • 感谢您的解释。这对我有用... [Environment]::SetEnvironmentVariable("Path", ([Environment]::GetEnvironmentVariable("Path", "User") + [IO.Path]::PathSeparator + "C:\Program Files \Java\jdk-13.0.2\bin"), "用户")
猜你喜欢
  • 1970-01-01
  • 2017-06-02
  • 2011-11-21
  • 1970-01-01
  • 1970-01-01
  • 2013-03-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多