代码之家  ›  专栏  ›  技术社区  ›  Vinnie James

如何在powershell中获取用户环境变量?

  •  1
  • Vinnie James  · 技术社区  · 6 年前

    我懂了 here ,可以在windows powershell中点源脚本。如何取而代之的是一个源用户的envvars(或者用户vars保存的文件路径)?

    示例.ps1:

    [Environment]::SetEnvironmentVariable("PATH", "C:\newapp\bin", "User")
    newapp --do-something # fails until PS restart
    
    1 回复  |  直到 6 年前
        1
  •  2
  •   Ansgar Wiechers    6 年前

    环境变量存储在注册表中,而不是文件中,它们在powershell启动时自动加载。没什么好点的。通过列出 env: 硬盘:

    PS C:\> Get-ChildItem env:
    
    Name                           Value
    ----                           -----
    ALLUSERSPROFILE                C:\ProgramData
    APPDATA                        C:\Users\jsmith\AppData\Roaming
    CommonProgramFiles             C:\Program Files\Common Files
    ...
    

    环境变量不同于常规powershell变量,它们必须通过 env 作用域前缀:

    PS C:\> $username = 'foo'    # ← PowerShell variable
    PS C:\> $username
    foo
    PS C:\> $env:username        # ← environment variable
    jsmith
    

    可以通过更改变量来修改当前环境

    PS C:\> $env:Path += ';C:\some\folder'    # append C:\some\folder to PATH
    

    或者完全替换它们:

    PS C:\> $env:Path = 'C:\some\folder'      # set PATH to C:\some\folder
    

    不建议操作环境变量,如 $env:USERNAME 但是。

    不过,请注意, 可以 修改环境变量或通过点源文件(在变量名中使用适当的前缀)加载这些变量不会持久化,因为它们只应用于流程环境。

    要对环境变量进行持久更改,需要在注册表中编辑值

    Set-ItemProperty -Path 'HKCU:\Environment' -Name 'foo' -Value 'bar' -Type String
    

    或者使用.net api

    [Environment]::SetEnvironmentVariable('foo', 'bar', 'User')
    

    当心有 pitfalls 通过api更改注册表值。

    使用 setx commandline实用程序也可以工作,但我不建议这样做,因为语法并不像人们希望的那样简单,powershell首先不需要外部程序。

    您还可以通过从注册表中重新读取环境变量的值来更新启动进程后更改的环境变量:

    $env:foo = [Environment]::GetEnvironmentVariable('foo', 'User')
    

    不过,请注意,windows将用户和系统环境存储在不同的位置。如果你有一个变量 $env:Path 在用户和系统环境中定义的,需要将这两个值组合在一起:

    $env:Path = [Environment]::GetEnvironmentVariable('Path', 'Machine') + ';' +
                [Environment]::GetEnvironmentVariable('Path', 'User')
    

    如果需要为当前进程同时更改环境变量 持久化您需要执行两个操作:更改 $env:VARIABLE 并将更改后的变量写回注册表。如果需要多次执行此操作,建议将这两个操作包装到自定义函数中,例如:

    function Set-EnvVariable {
        [CmdletBinding()]
        Param(
            [Parameter(Mandatory=$true)]
            [String]$Name,
            [Parameter(Mandatory=$true)]
            $Value,
            [Parameter(Mandatory=$false)]
            [String]$Type = 'String'
        )
    
        if (Test-Path -LiteralPath "env:$Name") {
            Set-Item "env:$Name" -Value $Value
        } else {
            New-Item -Path 'env:' -Name $Name -Value $value
        }
    
        Set-ItemProperty -Path 'HKCU:\Environment' -Name $Name -Value $Value -Type $Type
    }
    

    嗯,从技术上讲,注册表中包含用户环境变量的部分 存储在文件中 ntuser.dat 在用户的配置文件目录中。然而,在powershell中,这是任何人都不能点源代码的。