web-dev-qa-db-ja.com

Windows PowerShell環境変数を設定する

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

注意:

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

510
Vasil

実際の環境変数を変更するには、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
353
JaredPar

PowerShellセッション中にしばらくの間、PATH環境変数に一時的に追加する必要がある場合は、次のようにして実行できます。

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

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

### 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)
213
hoge

PowerShellプロンプトから:

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

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

SUCCESS: Specified value was saved.

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

このようにしてパスを変更する前に、PowerShellプロンプトで$env:path >> a.outを実行して既存のパスのコピーを必ず保存してください。

49
tjb

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 を調べてください。

21
Michael Kropat

現在受け入れられている答えは、パス変数が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
15
gijswijs

恒久的な変更を示唆するすべての回答に同じ問題があります。それらはパスレジストリ値を壊します。

SetEnvironmentVariableは、REG_EXPAND_SZ%SystemRoot%\system32REG_SZC:\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
 }

私はこの問題を ブログ投稿 でさらに詳しく説明します。

9
Peter Hahndorf

これは現在のセッションのパスを設定し、それを永久に追加するようにユーザーに促します。

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にあります。

8
JeanT

ほとんどの答えはアドレス指定ではありません 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
5
Jonathan

Jonathan Leadershere について述べたように、 '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
    }

}
5
Mehrdad Mirreza

@Michael Kropat's answerに基づいて、既存のPATHvariableの前に新しいパスを追加するパラメーターと、存在しないパスが追加されないようにするチェックを追加しました。

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

私の提案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(“;”)
1
ali Darabi

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;

これまでのところ、彼らはうまくいっているようです。

0
Eniola

PowerShellを開いて実行します。

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

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

詳細はこちら: https://docs.Microsoft.com/en-us/powershell/module/Microsoft.powershell.core/about/about_environment_variables?view=powershell-6

0
Paul Maurer