Установка переменной пути Windows PowerShell



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



Примечание:



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

1678   12  

12 ответов:

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

$env:Path = "SomeRandomPath";

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

c:\Users\JaredPar\Documents\WindowsPowerShell\profile.ps1

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

$env:Path += ";C:\Program Files\GnuWin32\bin"

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

### Modify system environment variable ###
[Environment]::SetEnvironmentVariable
     ( "Path", $env:Path, [System.EnvironmentVariableTarget]::Machine )

### Modify user environment variable ###
[Environment]::SetEnvironmentVariable
     ( "INCLUDE", $env:INCLUDE, [System.EnvironmentVariableTarget]::User )

### from comments ###
### Usage from comments - Add to the system environment variable ###
[Environment]::SetEnvironmentVariable("Path", $env:Path + ";C:\bin", [EnvironmentVariableTarget]::Machine)

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

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

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

SUCCESS: Specified value was saved.

перезапустите сеанс, и переменная будет доступна. setx также может использоваться для установки произвольных переменных. Типа setx /? в приглашении для документации.

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

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

подробнее здесь: http://blogs.technet.com/b/heyscriptingguy/archive/2011/07/23/use-powershell-to-modify-your-environmental-path.aspx

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

Add-PathVariable "C:\NewFolderToAddToTheList" -Target Machine

как ответ Жанта, Я хотел абстракцию вокруг добавления к пути. В отличие от ответа Жанта мне нужно было запустить его без взаимодействия с пользователем. Другое поведение, которое я искал:

  • обновления $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 ';'
    }
}

проверить мой Гист соответствующего

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

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.

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

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
 }

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

Как Лидеры Джонатан указано здесь, важно запустить команду / скрипт повышен, чтобы иметь возможность изменять переменные среды для 'машина', но запуск некоторых команд с повышенными правами не должен выполняться с расширениями сообщества, поэтому я хотел бы изменить и расширить 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. Это касается вопросов ОАК.

Сначала установите расширения сообщества PowerShell: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

дом на @Майкл 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 ';'
            }
        }
    }
}

ВОТ МОЕ ПРЕДЛОЖЕНИЕ я проверил это, чтобы добавить C:\oracle\x64\bin чтобы Путь постоянно и это работает нормально.

$ENV:PATH

первый способ-это просто сделать:

$ENV:PATH=”$ENV:PATH;c:\path\to\folder”

но это изменение не постоянно, $env: path по умолчанию вернется к тому, что было раньше, как только вы закроете свой терминал powershell и снова откроете его. Это связано с тем, что вы применили изменение на уровне сеанса, а не на уровне источника (который является уровнем реестра). Для просмотра глобальное значение $env: path, do:

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 выглядит так, как вы хотите, чтобы он выглядел, если нет, то вы можете повредить свою ОС.

теперь применить новые значение:

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\Contro
l\Session Manager\Environment’ -Name PATH).Path

теперь вы можете перезагрузить терминал powershell (или даже перезагрузить машину) и увидеть, что он не откатывается к своему старому значению снова. Обратите внимание, что порядок путей может измениться так, что он находится в алфавитном порядке, поэтому убедитесь, что вы проверяете всю строку, чтобы упростить ее, вы можете разделить вывод на строки, используя точку с запятой в качестве делимметра:

($env:path).split(“;”)

Comments

    Ничего не найдено.