PATH環境変数を設定しても、古いコマンドのプロンプトにしか影響しないことがわかりました。 PowerShellは異なる環境設定を持っているようです。 PowerShell(v1)の環境変数を変更する方法
注意:
変更を永続的なものにしたいので、PowerShellを実行するたびに設定する必要はありません。 PowerShellにはプロファイルファイルがありますか? Unix上のBashプロファイルのようなもの?
実際の環境変数を変更するには、env: namespace / drive
情報を使用します。たとえば、次のコードはpath環境変数を更新します。
$env:Path = "SomeRandomPath"; (replaces existing path)
$env:Path += ";SomeRandomPath" (appends to existing path)
環境設定を永続的にする方法はいくつかありますが、それらをPowerShellからのみ使用している場合は、プロファイルを使用して設定を開始したほうがはるかに良いでしょう。起動時に、PowerShellはマイドキュメントフォルダの下のWindowsPowerShell
ディレクトリにある .ps1 ファイルをすべて実行します。通常、 profile.ps1 というファイルがすでにあります。私のコンピュータ上のパスは
C:\Users\JaredPar\Documents\WindowsPowerShell\profile.ps1
PowerShellセッション中にしばらくの間、PATH環境変数に一時的に追加する必要がある場合は、次のようにして実行できます。
$env:Path += ";C:\Program Files\GnuWin32\bin"
次のようにして、ユーザー/システム環境変数を恒久的に変更することもできます(シェルを再起動しても持続します)。
### 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)
PowerShellプロンプトから:
setx PATH "$env:path;\the\directory\to\add" -m
テキストが表示されます。
SUCCESS: Specified value was saved.
セッションを再開すると、変数が利用可能になります。 setx
は任意の変数を設定するためにも使用できます。ドキュメンテーションのプロンプトでsetx /?
を入力します。
このようにしてパスを変更する前に、PowerShellプロンプトで$env:path >> a.out
を実行して既存のパスのコピーを必ず保存してください。
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
関数については、 my Gist を調べてください。
現在受け入れられている答えは、パス変数が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
値%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
}
私はこの問題を ブログ投稿 でさらに詳しく説明します。
これは現在のセッションのパスを設定し、それを永久に追加するようにユーザーに促します。
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
にあります。
ほとんどの答えはアドレス指定ではありません UAC 。これはUACの問題をカバーしています。
最初にPowerShell Community Extensionsをインストールします:choco install pscx
via 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
Jonathan Leaders が here について述べたように、 'machine' の環境変数を変更できるように昇格したコマンド/スクリプトを実行することが重要ですが、いくつかのコマンドを実行します。また、システム変数を変更しても実行できるように、 JeanT'sanswer }を変更して拡張したいと思います。スクリプト自体は実行されません。
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
}
}
@Michael Kropat's answerに基づいて、既存のPATH
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 ';'
}
}
}
}
私の提案ISこの1つは、PathにC:\ Oracle\x64\binを追加することを恒久的にテストしたもので、これでうまくいきます。
$ENV:PATH
最初の方法は単純にすることです:
$ENV:PATH=”$ENV:PATH;c:\path\to\folder”
しかし、この変更は恒久的なものではありません。$ env:pathは、PowerShell端末を閉じて再び開くとすぐにデフォルトの設定に戻ります。これは、ソースレベル(レジストリレベル)ではなくセッションレベルで変更を適用したためです。 $ env:pathのグローバル値を表示するには、次のようにします。
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があなたの望み通りの外観になっていることを確認してください。そうでなければあなたのOSにダメージを与える可能性があります。
今新しい値を適用します。
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(“;”)
SBFの および Michaelの を最適化して、よりコンパクトにしました。
私は自動的に文字列を列挙値に変換するPowerShellの型強制に依存しているので、ルックアップ辞書を定義しませんでした。
私はまた、条件に基づいて新しいパスをリストに追加するブロックを取り出したので、作業は一度行われ、再利用のために変数に格納されます。
その後、$PathContainer
パラメータに応じて、永続的にまたは単にセッションに適用されます。
コードブロックは、Promptコマンドから直接呼び出す関数またはps1ファイルに入れることができます。私はDevEnvAddPath.ps1と行きました。
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.ps1のために同様のことをします。
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を開いて実行します。
[Environment]::SetEnvironmentVariable("PATH", "$ENV:PATH;<path to exe>", "USER")
Powershell内で、次のように入力して環境変数ディレクトリに移動できます。
Set-Location Env:
これにより、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