如何从PowerShell中的脚本文件重新加载用户配置文件

时间:2009-02-19 23:02:19

标签: powershell profile

我想从脚本文件重新加载我的用户个人资料。我认为从脚本文件中获取点可以解决问题,但它不起作用:

# file.ps1
. $PROFILE

但是,如果我从PowerShell的解释器中获取源代码,它确实有效。

为什么我要这样做?

我每次更新配置文件时都会运行此脚本并想测试它,所以我想避免重新启动PowerShell来刷新环境。

8 个答案:

答案 0 :(得分:28)

如果要从脚本全局刷新配置文件,则必须运行该脚本“dot-sourced”。

运行脚本时,所有配置文件脚本都在“脚本”范围内运行,不会修改“全局”范围。

为了让脚本修改您的全局范围,它必须是“点源”或以句点开头。

. ./yourrestartscript.ps1

在“yourrestartscript.ps1”中有你的个人资料脚本“dot-sourced”。你实际上在做的是告诉“yourrestartscript”在当前范围内运行并在该脚本中,你告诉$ profile脚本在脚本的范围内运行。由于脚本的范围是全局范围,因此配置文件中的任何变量集或命令都将在全局范围内发生。

这不会比跑步更有利于你

. $profile

答案 1 :(得分:26)

因此,您标记为答案的方法可能在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 $_"
            . $_
        }
    }    
}

答案 2 :(得分:5)

& $profile   

可以重新加载个人资料。

如果您的配置文件设置别名或执行失败的导入,那么您将看到错误,因为它们已在先前加载的配置文件中设置。

答案 3 :(得分:3)

你为什么要这样做?

因为它可能会创建重复项(附加到$ env:path)以及设置导致错误的常量/只读对象的问题。

最近在microsoft.public.windows.powershell上有关于此主题的帖子。

如果您尝试重置会话状态,则无法执行此操作,即使使用内部作用域($host.EnterNestedPrompt())也是如此,因为能够在“all”处设置变量/别名/ ...范围”。

答案 4 :(得分:2)

我发现了这个解决方法:

#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

答案 5 :(得分:0)

这只是guillermooo上面回答的两行脚本的改进,它没有让新的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
}

通过权利它不应该工作,因为它吐出的命令行格式不正确,但似乎做了这项工作,这对我来说已经足够了。

答案 6 :(得分:0)

我用它来解决永久性加载哪些配置文件的问题。

开始运行:

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使我更接近发现我的问题。

答案 7 :(得分:-1)

因为几年后我偶然发现了这个问题,我想补充一点,您可以使用调用运算符&将您的个人资料加载到您的个人资料中的默认变量:$profile

所以,如果你的会话以某种方式无法加载你的个人资料(发生在cmder / conemu上),请输入:

& $profile