Настройка переменных среды Windows PowerShell - PullRequest
520 голосов
/ 03 апреля 2009

Я обнаружил, что установка переменной среды PATH влияет только на старую командную строку. В PowerShell, похоже, разные настройки среды. Как изменить переменные среды для PowerShell (v1)?

Примечание:

Я хочу сделать свои изменения постоянными, поэтому мне не нужно их устанавливать каждый раз, когда я запускаю PowerShell. Есть ли в PowerShell файл профиля? Что-то вроде профиля Bash в Unix?

Ответы [ 14 ]

594 голосов
/ 26 августа 2009

Если какое-то время во время сеанса PowerShell вам необходимо временно добавив переменную окружения PATH, вы можете сделать это так:

$env:Path += ";C:\Program Files\GnuWin32\bin"
365 голосов
/ 03 апреля 2009

Изменение фактических переменных среды может быть сделано с помощью используя информацию env: namespace / drive. Например, это Код обновит переменную окружения пути:

$env:Path = "SomeRandomPath";             (replaces existing path) 
$env:Path += ";SomeRandomPath"            (appends to existing path)

Есть способы сделать настройки среды постоянными, но если вы используете их только из PowerShell, это, вероятно, намного лучше использовать свой профиль, чтобы начать Настройки. При запуске PowerShell запустит любую .ps1 файлы, которые он находит в каталоге WindowsPowerShell в Папка «Мои документы». Обычно у вас есть profile.ps1 файл уже там. Путь на моем компьютере

C:\Users\JaredPar\Documents\WindowsPowerShell\profile.ps1
219 голосов
/ 03 апреля 2010

Вы также можете постоянно изменять переменные среды пользователя / системы (то есть будут постоянными при перезапуске оболочки) следующим образом:

### 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)
50 голосов
/ 09 января 2012

Из командной строки PowerShell:

setx PATH "$env:path;\the\directory\to\add" -m

Вы должны увидеть текст:

SUCCESS: Specified value was saved.

Перезапустите сеанс, и переменная будет доступна. setx также может использоваться для установки произвольных переменных. В командной строке введите setx /?.

Перед тем, как возиться с вашим путем, убедитесь, что вы сохранили копию существующего пути, выполнив $env:path >> a.out в приглашении PowerShell.

22 голосов
/ 18 января 2016

Как и Ответ 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.

15 голосов
/ 17 декабря 2014

Хотя текущий принятый ответ работает в том смысле, что переменная пути постоянно обновляется из контекста 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 для изменения вашего экологического пути

Если вы используете расширения сообщества PowerShell, правильная команда для добавления пути к пути переменной среды:

Add-PathVariable "C:\NewFolderToAddToTheList" -Target Machine
9 голосов
/ 10 октября 2016

Все ответы, предлагающие постоянное изменение, имеют одну и ту же проблему: они нарушают значение реестра пути.

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
 }

Я объясню проблему более подробно в сообщении в блоге .

8 голосов
/ 07 июня 2015

Устанавливает путь для текущего сеанса и предлагает пользователю добавить его навсегда:

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'
    }
}

Вы можете добавить эту функцию в свой профиль по умолчанию (Microsoft.PowerShell_profile.ps1), обычно расположенный по адресу %USERPROFILE%\Documents\WindowsPowerShell.

5 голосов
/ 04 мая 2016

Поскольку Jonathan Leaders упомянул здесь , важно запустить команду / скрипт с повышенными правами, чтобы иметь возможность изменять переменные среды для 'machine' , но запуск некоторых команд с повышенными правами необязательно выполнять с помощью расширений сообщества, поэтому я хотел бы изменить и расширить JeanT answer таким образом, чтобы изменение машинных переменных также могло быть выполняется, даже если сам скрипт не запущен с повышенными правами:

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
    }

}
5 голосов
/ 19 февраля 2015

Большинство ответов не адресовано UAC . Это касается вопросов UAC.

Первая установка PowerShell Community Extensions: choco install pscx через http://chocolatey.org/ (может потребоваться перезапустить среду оболочки).

Затем включите PSCX

Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser #allows scripts to run from the interwebs, such as pcsx

Тогда используйте Invoke-Elevated

Invoke-Elevated {Add-PathVariable $args[0] -Target Machine} -ArgumentList $MY_NEW_DIR
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...