Установка переменных среды Windows PowerShell

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

Примечание:

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

Комментарии к вопросу (3)

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

$env:Path += ";C:\Program Files\GnuWin32\bin"
Комментарии (7)
Решение

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

$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
Комментарии (8)

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

Изменить системную переменную окружения

[Environment]::SetEnvironmentVariable
     ("Path", $env:Path, [System.EnvironmentVariableTarget]::Machine)

Изменение переменной окружения пользователя

[Environment]::SetEnvironmentVariable
     ("INCLUDE", $env:INCLUDE, [System.EnvironmentVariableTarget]::User)

Использование из комментариев - добавить в системную переменную окружения

[Environment]::SetEnvironmentVariable(
    "Path",
    [Environment]::GetEnvironmentVariable("Path", [EnvironmentVariableTarget]::Machine) + ";C:\bin",
    [EnvironmentVariableTarget]::Machine)

Решение на основе строк также возможно, если вы не хотите писать типы

[Environment]::SetEnvironmentVariable("Path", $env:Path + ";C:\bin", "Machine")
Комментарии (11)

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

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

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

SUCCESS: Specified value was saved.

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

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

Комментарии (4)

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

  • Обновления `$env:в путь, чтобы изменения вступили в силу в текущем сеансе
  • Сохраняется в переменной окружения изменить для будущих сессий
  • Не'т добавить дубликат путь, когда один и тот же путь уже существует

В случае, если он's полезный, вот это:

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

Проверьте моя суть для соответствующего удаления-EnvPath функции.

Комментарии (0)

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

Более подробная информация в блоге использовать PowerShell, чтобы изменить экологическую тропу

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

Add-PathVariable "C:\NewFolderToAddToTheList" -Target Machine
Комментарии (0)

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

SetEnvironmentVariable превращает reg_expand_sz для значение %Системный_корневой_каталог%\System32 " в " типа reg_sz значение C:\Windows\system32.

Любые другие переменные в пути, а также потерял. Добавить новые с помощью %myNewPath% выиграл't работать больше.

Здесь'ы сценария набор-PathVariable.пс1, который я использую для решения этой проблемы:

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

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

Комментарии (1)

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

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

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

Комментарии (0)

Опираясь на [@Майкл Kropat'С][1] ответ я добавил параметр, чтобы добавить новый путь к существующему пути'variable и проверить, чтобы избежать добавления несуществующий путь:

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

[1]: https://stackoverflow.com/a/34844707/1509300 на "Майкл Kropat"и

Комментарии (0)

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

}
Комментарии (0)

Большинство ответов не'т решение ОАК. Это касается проблем с UAC.

Сначала установите сообщества расширения PowerShell: Шоко установить pscx аппликации через http://chocolatey.org/ (возможно, придется перезагрузить среде оболочки).

Затем включите pscx аппликации

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

Затем использовать вызвать повышенных

Invoke-Elevated {Add-PathVariable $args[0] -Target Machine} -ArgumentList $MY_NEW_DIR
Комментарии (0)

Откройте PowerShell и выполните:

[Environment]::SetEnvironmentVariable("PATH", "$ENV:PATH;<path to exe>", "USER")
Комментарии (0)

Мое предложение таково:

Я испытал это, чтобы добавить C:\oracle\x64\bin к переменной окруженияPATH` постоянно и это прекрасно работает.

$ENV:PATH

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

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

Но это изменение не является постоянным. $env:в путь по умолчанию то, что было раньше, как только вы закрываете терминал PowerShell и снова откройте его. Это потому, что вы применили изменения на уровне сессии, а не на уровне исходного кода (на уровне реестра). Просмотреть глобальное значение `$env:в путь, не так:

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

Теперь вы можете перезапустить ваш терминал PowerShell (или даже перезагрузить компьютер) и видим, что это не откат до старых значений.

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

($env:path).split(“;”)
Комментарии (0)

Я пытался оптимизировать СБФ'С и Михаил'С код немного, чтобы сделать его более компактным.

Я опираюсь о PowerShell'с приведением типа, где он автоматически преобразует строки В значения перечислений, поэтому я не'т определить словарь подстановок.

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

Он применяется постоянно или только на время сеанса, в зависимости от параметра $PathContainer.

Мы можем поставить блок кода в функцию или файл PS1, который мы называем непосредственно из командной строки. Я пошел с DevEnvAddPath.пс1.

param(
    [Parameter(Position=0,Mandatory=$true)][String]$PathChange,

    [ValidateSet('Machine', 'User', 'Session')]
    [Parameter(Position=1,Mandatory=$false)][String]$PathContainer='Session',
    [Parameter(Position=2,Mandatory=$false)][Boolean]$PathPrepend=$false
)

[String]$ConstructedEnvPath = switch ($PathContainer) { "Session"{${env:Path};} default{[Environment]::GetEnvironmentVariable('Path', $containerType);} };
$PathPersisted = $ConstructedEnvPath -split ';';

if ($PathPersisted -notcontains $PathChange) {
    $PathPersisted = $(switch ($PathPrepend) { $true{,$PathChange + $PathPersisted;} default{$PathPersisted + $PathChange;} }) | Where-Object { $_ };

    $ConstructedEnvPath = $PathPersisted -join ";";
}

if ($PathContainer -ne 'Session') 
{
    # Save permanently to Machine, User
    [Environment]::SetEnvironmentVariable("Path", $ConstructedEnvPath, $PathContainer);
}

# Update the current session
${env:Path} = $ConstructedEnvPath;

Я что-то похожее на DevEnvRemovePath.пс1.

param(
    [Parameter(Position=0,Mandatory=$true)][String]$PathChange,

    [ValidateSet('Machine', 'User', 'Session')]
    [Parameter(Position=1,Mandatory=$false)][String]$PathContainer='Session'
)

[String]$ConstructedEnvPath = switch ($PathContainer) { "Session"{${env:Path};} default{[Environment]::GetEnvironmentVariable('Path', $containerType);} };
$PathPersisted = $ConstructedEnvPath -split ';';

if ($PathPersisted -contains $PathChange) {
    $PathPersisted = $PathPersisted | Where-Object { $_ -ne $PathChange };

    $ConstructedEnvPath = $PathPersisted -join ";";
}

if ($PathContainer -ne 'Session') 
{
    # Save permanently to Machine, User
    [Environment]::SetEnvironmentVariable("Path", $ConstructedEnvPath, $PathContainer);
}

# Update the current session
${env:Path} = $ConstructedEnvPath;

До сих пор они, кажется, работают.

Комментарии (0)

В PowerShell, то можно перейти к переменной каталог среда, введя:

Set-Location Env:

Это приведет вас к ОКР: каталог>. В этот каталог:

Чтобы посмотреть все переменные окружения, типа:

Env:\> Get-ChildItem

Чтобы увидеть конкретную переменную окружения, типа:

Env:\> $Env:, e.g. $Env:Path

Чтобы задать переменную среды, типа:

Env:\> $Env: = "", e.g. $Env:Path="C:\Users\"

Чтобы удалить переменную окружения, типа:

Env:\> remove-item Env:, e.g. remove-item Env:SECRET_KEY

Более подробная информация в переменные среды.

Комментарии (0)