Windows PowerShell環境変数の設定


608

PATH環境変数を設定すると、古いコマンドプロンプトにのみ影響することがわかりました。PowerShellの環境設定が異なっているようです。PowerShell(v1)の環境変数を変更するにはどうすればよいですか?

注意:

変更を永続的にしたいので、PowerShellを実行するたびに設定を変更する必要はありません。PowerShellにはプロファイルファイルがありますか?UnixのBashプロファイルのようなものですか?


1
ファイル共有に中央プロファイルを配置したいのですが。同期は苦痛です。を使用してスタブプロファイルを作成します。\\ computer \ share \ path \ Profile.ps1は扱いにくいようです(メモ帳の$ Profileを試してください)。$ Profile自動変数を永続的に変更する方法があったらいいですね。
Nathan Hartley、

5
PATH環境、Powershellコマンドプロンプトにも影響しません。ただし、Powershellは引用符で囲まれたパスを受け入れないという点が異なります。解決策:"パス環境変数内のすべての囲み引用符()を削除します
Nilzor

3
これは、セッションのPATH環境変数にパスから「すべてを除去するために使用:さらに上記NilzorさんのコメントにPS> v1のためにここでIF YOU LAND ...$($Env:PATH).Split(';') | %{ $str += "$($_.Trim('"'));" }; $Env:PATH=$str
d3r3kk

回答:


479

実際の環境変数の変更は、このenv: namespace / drive情報を使用して行うことができます。たとえば、次のコードはパス環境変数を更新します。

$env:Path = "SomeRandomPath";             (replaces existing path) 
$env:Path += ";SomeRandomPath"            (appends to existing path)

環境設定を永続的にする方法はいくつかありますが、PowerShellからのみ環境設定を使用する場合は、プロファイルを使用して設定を開始する方がはるかに良いでしょう。起動時に、PowerShellはMy Documentsフォルダーの下 のディレクトリにある.ps1ファイルを実行しWindowsPowerShellます。通常は、profile.ps1 ファイルが既に存在します。私のコンピューター上のパスは

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

38
$ profileは、すべてのPowerShellホストのユーザープロファイルを指す自動変数です。
JasonMArcher、2009

16
(スプリットパス$ profile)(格納フォルダーを取得するため)には複数のプロファイルファイルを含めることができます。profile.ps1は、すべてのホストによってロードされる必要があります。<host-name> _profile.ps1は、指定されたホストによってのみロードされます。PowerShell.exe(コンソールホスト)の場合、これはMicrosoft.PowerShell_profile.ps1です。
リチャード

10
ドキュメントにWindowsPowerShellフォルダーがない場合はどうなりますか?フォルダーとファイルを作成する必要がありますか?C:\path\to\file.ext環境変数に追加したい場合、ファイルに何を入れればよいですか?編集:すでに見つかりました。答えは「はい」です。作成してください。ファイルは1行で構成する必要があります:$env:path += ;C:\path\to\file.ext"
Lewistrick 2015年

7
@Lewistrickデフォルトではプロファイルがありません。これらの手順に従って作成しました:howtogeek.com/50236/customizing-your-powershell-profile
MikeB

16
これを行う場合は注意してください。既存のパスが破壊されます。 $env:Path = "SomeRandomPath"; 代わりに、以下の@mloskotを参照してください。
John Mark

626

PowerShellセッション中に、一時的にPATH環境変数に一時的に追加する必要がある場合は、次の方法で行うことができます。

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

4
+1 ::このワンライナーは、mingw ... IE $ env:PATH + = "; c:\ MinGW \ msys \ 1.0 \ bin" ^ {some mingw bin ...と同様に、セッションベースの呼び出しに非常に効果的です。 }
エディB

2
パスを削除するにはどうすればよいですか?
ベッコ

11
パスを標準パスの前に呼び出す必要がある場合は、最初に挿入します $env:Path = "C:\MyPath;$env:Path"
Michael Freidgeim

4
**** @Kevinのコメントにあるように、追加文字列の先頭のセミコロンを忘れないでください。これはかなり明白ですが、回答のコードを単にコピー/貼り付けし、既存のパスの最後にセミコロンがない場合は見逃される可能性があります。編集を送信してみます。
Matt Goodrich

1
前のリビジョンに@MattGoodrich Iましたロールバック
・クール

278

次のようにして、ユーザー/システム環境変数を永続的に変更することもできます(つまり、シェルの再起動後も永続的になります)。

システム環境変数を変更する

[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")

6
これは、アクセスが制限されたシステムに非常に役立ちます。
h0tw1r3 2012

14
@AndresRiofrio、はい、これは永続的です。使用法:[Environment]::SetEnvironmentVariable("Path", $env:Path + ";C:\bin", [EnvironmentVariableTartget::Machine) 新しいPowerShellセッションを開始するまで、この変更の結果は表示されません。つまり、このコマンドを実行した直後に$ env:Pathを調べると、コマンドの前の$ env:Pathがわかります。更新するには、シェルを閉じて開くか、新しいセッションを開始します。
FLGMwt 14年

7
@FLGMwt入力ミスがあります。正しいのは、[Environment] :: SetEnvironmentVariable( "Path"、$ env:Path + "; C:\ bin"、​​[EnvironmentVariableTarget] :: Machine)
enthus1ast

10
.NET列挙型全体ではなく、文字列「Machine」または「User」を書き込むことができます。Technetから。
bouvierr 14

3
答えは、このようにユーザー変数を設定するための使用法も示す必要があると思います[Environment]::SetEnvironmentVariable("Path", [Environment]::GetEnvironmentVariable("Path", "User") + ";C:\bin", "User")
斎藤

63

PowerShellプロンプトから:

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

次に、テキストが表示されます。

SUCCESS: Specified value was saved.

セッションを再起動すると、変数が使用可能になります。setx任意の変数を設定するためにも使用できます。入力setx /?ドキュメントのプロンプトで。

この方法でパスをいじる前$env:path >> a.outに、PowerShellプロンプトで既存のパスのコピーを保存してください。


5
「管理者として実行中」の場合にのみ機能し、その後は「管理者として実行中」のPowerShellコンソールに対してのみ有効になり、定期的に実行されているコンソールでは機能しません。
matanster 2013


12
痛い-setxの1024文字の制限に達しました。ありがたいことに、私は$ end:Pathの既存の値を記録するためのアドバイスに従いました。注意すべきだけで何か:superuser.com/questions/387619/...
Jonno

3
$env:PATH最初に設定してから、setx /m PATH "$env:PATH"シェルの再起動なしでローカルおよびグローバルに適用されるようにしてください。
tresf

1
いいね!setxはネイティブのコマンドレットではありませんが、それでも、これらの厄介な長時間の.NET Framework呼び出しに代わるはるかに優れた、簡単に忘れられるものです!ただし、Powershell 7でさえも、envvarsを永続化する公式のコマンドレットがまだ付属していないのは困惑しています。何。「ls」と同等の機能のように感じます。
ジョナス

27

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


16

現在受け入れられている回答は、パス変数が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コミュニティ拡張機能を使用する場合、環境変数パスにパスを追加する適切なコマンドは次のとおりです。

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

12

永続的な変更を提案するすべての回答には同じ問題があります。パスのレジストリ値が壊れます。

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

この問題については、ブログの投稿で詳しく説明しています。


これは次のようになります:$ newPath = $ newPath -replace ";;"、 ";" ?
ジョージョンストン

8

これにより、現在のセッションのパスが設定され、永続的に追加するようにユーザーに求められます。

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


6

上に構築さ@Michael 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 ';'
            }
        }
    }
}

5

ジョナサンリーダーは述べたここで、コマンド/スクリプトはの変更環境変数にできるように上昇し実行することが重要である「マシン」が、上昇いくつかのコマンドを実行すると、私が好きなので、コミュニティの拡張機能で実行する必要はありません。ある方法で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
    }

}

5

ほとんどの回答はUACを扱っていません。これはUACの問題を扱います。

最初にPowerShell Community Extensionsをインストール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

4

私の提案はこれです:

これをテストしてC:\oracle\x64\bin、環境変数をPath永続的に追加しましたが、これは正常に機能します。

$ENV:PATH

最初の方法は単に行うことです:

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

ただし、この変更は永続的なものではありません。$env:pathPowerShellターミナルを閉じて再び開くと、デフォルトで以前の状態に戻ります。これは、ソースレベル(レジストリレベル)ではなく、セッションレベルで変更を適用したためです。のグローバル値を表示するには$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(“;”)

3

PowerShellを開いて実行します。

[Environment]::SetEnvironmentVariable("PATH", "$ENV:PATH;<path to exe>", "USER")

1

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

詳細については、「環境変数について」を参照してください。


0

SBFマイケルのコードを少し最適化して、よりコンパクトにしようとしました。

文字列を列挙値に自動的に変換するPowerShellの型強制に依存しているため、ルックアップディクショナリを定義していません。

また、条件に基づいてリストに新しいパスを追加するブロックを引き出したので、作業は一度行われ、変数に格納されて再利用されます。

その後、$PathContainerパラメーターに応じて、永続的にまたはセッションにのみ適用されます。

コードブロックを関数またはコマンドプロンプトから直接呼び出す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;

これまでのところ、それらは動作するようです。


0

値をレジストリにプッシュする回答のみが永続的な変更に影響します(したがって、このスレッドの回答の大部分(承認された回答を含む)はに永続的に影響しませんPath)。

次の関数は、Path/ PSModulePathおよびUser/ Systemタイプの両方で機能します。また、デフォルトで現在のセッションに新しいパスを追加します。

function AddTo-Path {
    param ( 
        [string]$PathToAdd,
        [Parameter(Mandatory=$true)][ValidateSet('System','User')][string]$UserType,
        [Parameter(Mandatory=$true)][ValidateSet('Path','PSModulePath')][string]$PathType
    )

    # AddTo-Path "C:\XXX" "PSModulePath" 'System' 
    if ($UserType -eq "System" ) { $RegPropertyLocation = 'HKLM:\System\CurrentControlSet\Control\Session Manager\Environment' }
    if ($UserType -eq "User"   ) { $RegPropertyLocation = 'HKCU:\Environment' } # also note: Registry::HKEY_LOCAL_MACHINE\ format
    $PathOld = (Get-ItemProperty -Path $RegPropertyLocation -Name $PathType).$PathType
    "`n$UserType $PathType Before:`n$PathOld`n"
    $PathArray = $PathOld -Split ";" -replace "\\+$", ""
    if ($PathArray -notcontains $PathToAdd) {
        "$UserType $PathType Now:"   # ; sleep -Milliseconds 100   # Might need pause to prevent text being after Path output(!)
        $PathNew = "$PathOld;$PathToAdd"
        Set-ItemProperty -Path $RegPropertyLocation -Name $PathType -Value $PathNew
        Get-ItemProperty -Path $RegPropertyLocation -Name $PathType | select -ExpandProperty $PathType
        if ($PathType -eq "Path") { $env:Path += ";$PathToAdd" }                  # Add to Path also for this current session
        if ($PathType -eq "PSModulePath") { $env:PSModulePath += ";$PathToAdd" }  # Add to PSModulePath also for this current session
        "`n$PathToAdd has been added to the $UserType $PathType"
    }
    else {
        "'$PathToAdd' is already in the $UserType $PathType. Nothing to do."
    }
}

# Add "C:\XXX" to User Path (but only if not already present)
AddTo-Path "C:\XXX" "User" "Path"

# Just show the current status by putting an empty path
AddTo-Path "" "User" "Path"
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.