如何在 PowerShell 中从脚本文件重新加载用户配置文件
-
05-09-2019 - |
题
我想从脚本文件重新加载我的用户配置文件。我认为从脚本文件中获取它的点可以解决问题,但它不起作用:
# file.ps1
. $PROFILE
但是,如果我不从 PowerShell 的解释器获取它,它确实可以工作。
我为什么要这样做?
我每次更新个人资料并想要测试它时都会运行此脚本,因此我希望避免重新启动 PowerShell 来刷新环境。
解决方案
所以,你标记为答案可能PowerShell命令提示符下内工作,但它不PowerShell的ISE(这对我来说,提供了优越的PowerShell会话)内工作,可能不会在正确的工作方法其他的PowerShell环境。
下面就是我一直在使用了一段脚本,它一直对我非常好每一个环境。我只是把这个功能到我Profile.ps1在〜\文档\ WindowsPowerShell,每当我想重装我的个人资料,我点源的功能,即。
. Reload-Profile
这里的功能:
function Reload-Profile {
@(
$Profile.AllUsersAllHosts,
$Profile.AllUsersCurrentHost,
$Profile.CurrentUserAllHosts,
$Profile.CurrentUserCurrentHost
) | % {
if(Test-Path $_){
Write-Verbose "Running $_"
. $_
}
}
}
其他提示
如果你想在全球范围内刷新从脚本您的个人资料,你必须运行该脚本“点源”。
当你运行你的脚本,所有的配置文件脚本的“脚本”范围内运行,并不会改变你的“全局”范围。
为了对一个脚本来修改全局范围,它需要被“点源”或前面有一个周期。
. ./yourrestartscript.ps1
,你必须“yourrestartscript.ps1”的配置文件脚本“点源”里。什么你实际上做的是告诉“yourrestartscript”在当前范围内运行,该脚本里面,你是在告诉$配置文件脚本在脚本的范围运行。由于脚本的范围是全球范围内,在您的配置文件中设置的变量或命令会发生在全球范围内。
这是不买你在运行太多的优势。
. $profile
& $profile
工作以重新加载配置文件。
如果您的个人资料设置别名或执行进口其失败,那么你将看到的错误,因为他们在配置文件中的先前加载已设置。
你为什么要尝试这样做?
因为它可能会创建重复项(附加到 $env:path),并且设置常量/只读对象会导致错误。
最近网上有一个关于这个话题的帖子 微软.public.windows.powershell.
如果您尝试重置会话的状态,则无法执行此操作,即使使用内部范围($host.EnterNestedPrompt()
)因为能够设置变量/别名/...在“所有范围”。
我发现这个解决方法:
#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
}
这是它不应该工作的权利,作为命令行就吐出来是畸形的,但似乎做的工作,这是很好的足以让我。
我用这个解决正在采取什么轮廓永远载入。
开始执行命令
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法塞特为我安排更接近于找到我的问题。
因为我无意中发现了这几年后,我想补充一点,你可以使用调用操作:&
与默认变量您的个人资料加载您的个人资料:$profile
所以,如果您的会话不知何故无法加载您的配置文件(恰好我cmder / conemu)只需键入:
& $profile