web-dev-qa-db-ja.com

PowerShellのスクリプトファイルからユーザープロファイルを再読み込みする方法

スクリプトファイルからユーザープロファイルを再読み込みしたいのですが。スクリプトファイル内からドットソースを使用するとうまくいくと思いましたが、機能しません。

# file.ps1
. $PROFILE

ただし、PowerShellのインタープリターからドットソース化した場合は機能します。

なぜこれをしたいのですか?

プロファイルを更新するたびにこのスクリプトを実行してテストしたいので、PowerShellを再起動して環境を更新する必要はありません。

39
guillermooo

したがって、回答としてマークしたアプローチは、Powershellコマンドプロンプト内で機能する可能性がありますが、PowerShell ISE(私にとっては、優れたPowerShellセッションを提供します)内では機能せず、おそらく他のPowerShell環境では正しく機能しません。 。

これは私がしばらく使用しているスクリプトですが、すべての環境で非常にうまく機能しています。この関数を〜\ Documents\WindowsPowerShellのProfile.ps1に配置するだけで、プロファイルを再読み込みするたびに、関数をドットソース化します。

. Reload-Profile

これが関数です:

function Reload-Profile {
    @(
        $Profile.AllUsersAllHosts,
        $Profile.AllUsersCurrentHost,
        $Profile.CurrentUserAllHosts,
        $Profile.CurrentUserCurrentHost
    ) | % {
        if(Test-Path $_){
            Write-Verbose "Running $_"
            . $_
        }
    }    
}
28
Winston Fassett

スクリプトからプロファイルをグローバルに更新する場合は、そのスクリプトを「ドットソース」で実行する必要があります。

スクリプトを実行すると、すべてのプロファイルスクリプトが「スクリプト」スコープで実行され、「グローバル」スコープは変更されません。

スクリプトでグローバルスコープを変更するには、「ドットソース」またはピリオドを前に付ける必要があります。

. ./yourrestartscript.ps1

「yourrestartscript.ps1」内にプロファイルスクリプト「dot-sourced」がある場所。実際に行っていることは、「yourrestartscript」に現在のスコープで実行するように指示し、そのスクリプト内で、$ profileスクリプトにスクリプトのスコープで実行するよう指示しています。スクリプトのスコープはグローバルスコープであるため、プロファイル内のすべての変数セットまたはコマンドはグローバルスコープで発生します。

それはランニングよりもあなたに多くの利点を買いません

. $profile
28
Steven Murawski
& $profile   

プロファイルをリロードします。

プロファイルがエイリアスを設定するか、失敗したインポートを実行する場合、それらはプロファイルの以前のロードですでに設定されているため、エラーが表示されます。

6
Lahru

なぜこれをやろうとしているのですか?

重複($ env:pathに追加)を作成する可能性が高く、定数/読み取り専用オブジェクトの設定で問題が発生してエラーが発生するためです。

Microsoft.public.windows.powershell にこのトピックに関するスレッドが最近ありました。

セッションの状態をリセットしようとしている場合は、変数/エイリアス/ ...を「すべてのスコープ」に設定できるため、内部スコープ($Host.EnterNestedPrompt())を使用してもこれを行う方法はありません。 」.

3
Richard

私はこの回避策を見つけました:

#some-script.ps1

#restart profile (open new powershell session)
cmd.exe /c start powershell.exe -c { Set-Location $PWD } -NoExit
Stop-Process -Id $PID

より精巧なバージョン:

#publish.ps1
# Copy profile files to PowerShell user profile folder and restart PowerShell
# to reflect changes. Try to start from .lnk in the Start Menu or
# fallback to cmd.exe.
# We try the .lnk first because it can have environmental data attached
# to it like fonts, colors, etc.

[System.Reflection.Assembly]::LoadWithPartialName("System.Diagnostics")

$dest = Split-Path $PROFILE -Parent
Copy-Item "*.ps1" $dest -Confirm -Exclude "publish.ps1" 

# 1) Get .lnk to PowerShell
# Locale's Start Menu name?...
$SM = [System.Environment+SpecialFolder]::StartMenu
$CurrentUserStartMenuPath = $([System.Environment]::GetFolderPath($SM))
$StartMenuName = Split-Path $CurrentUserStartMenuPath -Leaf                                 

# Common Start Menu path?...
$CAD = [System.Environment+SpecialFolder]::CommonApplicationData
$allUsersPath = Split-Path $([System.Environment]::GetFolderPath($CAD)) -Parent
$AllUsersStartMenuPath = Join-Path $allUsersPath $StartMenuName

$PSLnkPath = @(Get-ChildItem $AllUsersStartMenuPath, $CurrentUserStartMenuPath `
                                        -Recurse -Include "Windows PowerShell.lnk")

# 2) Restart...
# Is PowerShell available in PATH?
if ( Get-Command "powershell.exe" -ErrorAction SilentlyContinue ) {

    if ($PSLnkPath) {

        $pi = New-Object "System.Diagnostics.ProcessStartInfo"
        $pi.FileName = $PSLnkPath[0]
        $pi.UseShellExecute = $true

        # See "powershell -help" for info on -Command
        $pi.Arguments = "-NoExit -Command Set-Location $PWD"

        [System.Diagnostics.Process]::Start($pi)
    }
    else { 

        # See "powershell -help" for info on -Command
        cmd.exe /c start powershell.exe -Command { Set-Location $PWD } -NoExit
    }
}
else {
    Write-Host -ForegroundColor RED "Powershell not available in PATH."
}

# Let's clean up after ourselves...
Stop-Process -Id $PID
2
guillermooo

これは、上記のguillermoooの回答にある2行のスクリプトを改良したものであり、新しいPowerShellウィンドウを正しいディレクトリに入れませんでした。これは、$ PWDが新しいPowerShellウィンドウのコンテキストで評価されるためであると考えています。これは、set-locationで処理する値ではありません。

function Restart-Ps {
$cline = "`"/c start powershell.exe -noexit -c `"Set-Location '{0}'" -f $PWD.path
cmd $cline
Stop-Process -Id $PID
}

当然のことながら、吐き出されたコマンドラインの形式が正しくないため機能しませんが、それで問題が解決するようで、それで十分です。

0
Alex

数年後にこれに遭遇したので、呼び出し演算子を使用できると付け加えようと思いました:&デフォルトの変数を使用してプロファイルをプロファイルにロードするには、$profile

そのため、セッションが何らかの形でプロファイルのロードに失敗した場合(cmder/conemuで私に起こる)、次のように入力します。

& $profile

0
Dan W. Link

これを使用して、ロードするために永久にかかっているプロファイルをトラブルシューティングしました。

実行を開始:

powershell_ise -noprofile

次に、これを実行しました:

function Reload-Profile {
    @(
        $Profile.AllUsersAllHosts,
        $Profile.AllUsersCurrentHost,
        $Profile.CurrentUserAllHosts,
        $Profile.CurrentUserCurrentHost
    ) | % {
        if(Test-Path $_){
            Write-Verbose "Running $_"
            $measure = Measure-Command {. $_}
            "$($measure.TotalSeconds) for $_"
        }
    }    
}

. Reload-Profile

@Winston Fassettに問題を見つけてくれてありがとう。

0
Omzig