如何在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 }
按权利,它不应该工作,因为它吐出的命令行是畸形的,但它似乎做的工作,这对我来说已经足够了。