Я обнаружил, что установка переменной среды PATH влияет только на старую командную строку. Похоже, что PowerShell имеет другие настройки среды. Как изменить переменные среды для PowerShell (v1)?
Примечание:
Я хочу сделать свои изменения постоянными, чтобы не устанавливать их каждый раз при запуске PowerShell. Есть ли у PowerShell файл профиля? Что-то вроде профиля Bash в Unix?
Изменение фактических переменных окружения может быть сделано с помощью
используя информацию 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
Вы также можете изменять переменные окружения пользователя/системы постоянно (т.е. будут сохраняться при перезагрузке оболочки) с помощью следующего:
Изменить системную переменную окружения
[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")
Из командной строке PowerShell:
setx PATH "$env:path;\the\directory\to\add" -m
Затем вы должны увидеть текст:
SUCCESS: Specified value was saved.
Перезапустите сеанс, а переменная будет доступна. setx
также можно использовать для задания произвольных переменных. Типа setx /?` в строке для документации.
Прежде чем возиться с ваш путь в этот путь, убедитесь, что вы сохранить копию существующего пути, делая `$env:в путь >> а.выйти в командную строку PowerShell.
Как JeanT'ы ответ, я хотел абстракция вокруг, добавляя к пути. В отличие от JeanT'ы ответ я должна работать без взаимодействия с пользователем. Другого поведения я ищу:
В случае, если он'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 функции.
Хотя нынешний принятый ответ работает в том смысле, что переменной 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
Ответы на все вопросы, предполагая, что постоянные изменения имеют те же проблемы: они разбивают путь значением реестре.
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
}
Я объяснить более подробно проблему в блоге.
Это задает путь для текущей сессии, и предлагает пользователю добавить его навсегда:
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
.
Опираясь на [@Майкл 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"и
Как Джонатан лидеров упоминается здесь, важно выполнить команду/скрипт возвышенности, чтобы иметь возможность изменить переменные окружения для 'машина', но для запуска некоторых команд повышенные не'т иметь, чтобы быть сделано с сообществом расширения, так что я'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
}
}
Большинство ответов не'т решение ОАК. Это касается проблем с 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
Откройте PowerShell и выполните:
[Environment]::SetEnvironmentVariable("PATH", "$ENV:PATH;<path to exe>", "USER")
Мое предложение таково:
Я испытал это, чтобы добавить 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(“;”)
Я пытался оптимизировать СБФ'С и Михаил'С код немного, чтобы сделать его более компактным.
Я опираюсь о 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;
До сих пор они, кажется, работают.
В PowerShell, то можно перейти к переменной каталог среда, введя:
Set-Location Env:
Это приведет вас к ОКР: каталог>. В этот каталог:
Чтобы посмотреть все переменные окружения, типа:
Env:\> Get-ChildItem
Чтобы увидеть конкретную переменную окружения, типа:
Env:\> $Env:<variable name>, e.g. $Env:Path
Чтобы задать переменную среды, типа:
Env:\> $Env:<variable name> = "<new-value>", e.g. $Env:Path="C:\Users\"
Чтобы удалить переменную окружения, типа:
Env:\> remove-item Env:<variable name>, e.g. remove-item Env:SECRET_KEY
Более подробная информация в переменные среды.