Установка переменной пути Windows PowerShell
Я обнаружил, что установка переменной среды PATH влияет только на старую командную строку. PowerShell, похоже, имеет разные параметры среды. Как изменить переменные среды для PowerShell (v1)?
Примечание:
Я хочу сделать мои изменения постоянными, поэтому мне не нужно устанавливать его каждый раз, когда я запускаю PowerShell. Есть ли у PowerShell файл профиля? Что-то вроде профиля Bash на Unix?
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-ElevatedInvoke-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