如何在PowerShell中从脚本文件重新加载用户configuration文件

我想从脚本文件重新加载我的用户configuration文件。 我以为从脚本文件中获取它的点会做到这一点,但它不起作用:

# file.ps1 . $PROFILE 

然而,如果我从PowerShell的解释器中find它,它确实有效。

我为什么要这样做?

我每次更新我的configuration文件时都运行这个脚本,并且想testing它,所以我想避免重新启动PowerShell来刷新环境。

因此,您标记为答案的方法可能在Powershell命令提示符下工作,但在PowerShell ISE(对我来说,这提供了一个优秀的PowerShell会话)内不起作用,并且可能无法在其他PowerShell环境中正常工作。

以下是我已经使用了一段时间的脚本,并且在任何环境下都能很好地工作。 我只是把这个函数放在我的Profile.ps1的〜\ Documents \ WindowsPowerShell中,每当我想重新加载我的configuration文件,我点源的function,即

 . Reload-Profile 

这个function:

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

如果您想从脚本全局刷新您的configuration文件,则必须运行该脚本“点源”。

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

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

 . ./yourrestartscript.ps1 

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

这不会给你带来太多的优势

 . $profile 

你为什么要这么做?

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

最近在microsoft.public.windows.powershell上有一个关于这个话题的话题。

如果试图重置会话的状态,那么即使使用内部作用域( $host.EnterNestedPrompt() ),也无法做到这一点,因为可以在所有范围内设置variables/别名/ …。 。

 & $profile 

工程重新加载configuration文件。

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

我发现这个解决方法:

 #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 

这只是上面的guillermooo的答案中的两行脚本的改进,没有把新的PowerShell窗口放到正确的目录中。 我相信这是因为$ PWD是在新的PowerShell窗口的上下文中进行评估的,而这并不是我们想要设置的位置值。

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

按权利,它不应该工作,因为它吐出的命令行是畸形的,但它似乎做的工作,这对我来说已经足够了。