PowerShell에서 스크립트 파일에서 사용자 프로필을 다시로드하는 방법
-
05-09-2019 - |
문제
스크립트 파일에서 사용자 프로필을 다시로드하고 싶습니다. 스크립트 파일 내에서 DOT를 소싱한다고 생각했지만 트릭을 수행 할 것이라고 생각했지만 작동하지 않습니다.
# file.ps1
. $PROFILE
그러나 PowerShell의 통역사에서 소스를 점유하면 작동합니다.
왜 이것을하고 싶습니까?
프로필을 업데이트하고 테스트하고 싶을 때 마다이 스크립트를 실행하므로 환경을 새로 고치기 위해 PowerShell을 다시 시작하지 않아도됩니다.
해결책
따라서 답으로 표시된 접근 방식은 PowerShell 명령 프롬프트 내부에서 작동 할 수 있지만 PowerShell ISE (나에게 우수한 PowerShell 세션을 제공 함) 내부에서는 작동하지 않으며 다른 PowerShell 환경에서는 제대로 작동하지 않을 것입니다. .
다음은 한동안 사용해온 스크립트가 있으며 모든 환경에서 저에게 매우 효과적이었습니다. 이 기능을 단순히 내 프로필에 넣습니다.
. Reload-Profile
기능은 다음과 같습니다.
function Reload-Profile {
@(
$Profile.AllUsersAllHosts,
$Profile.AllUsersCurrentHost,
$Profile.CurrentUserAllHosts,
$Profile.CurrentUserCurrentHost
) | % {
if(Test-Path $_){
Write-Verbose "Running $_"
. $_
}
}
}
다른 팁
스크립트에서 프로필을 전역적으로 새로 고치려면 해당 스크립트를 "Dot-Sourced"로 실행해야합니다.
스크립트를 실행할 때 모든 프로필 스크립트는 "스크립트"범위로 실행되며 "글로벌"범위를 수정하지 않습니다.
스크립트가 글로벌 범위를 수정하려면 "도트 소스"이거나 기간에 앞서야합니다.
. ./yourrestartscript.ps1
"YourRestArtScript.ps1"내부에 프로필 스크립트 "Dot-Sourced"가있는 경우. 실제로하고있는 일은 "YourRestartScript"에 현재 범위와 해당 스크립트 내에서 실행되도록하는 것입니다. $ 프로필 스크립트에 스크립트의 범위에서 실행되도록 알려줍니다. 스크립트의 범위는 글로벌 범위이므로 프로필의 모든 변수 또는 명령이 전역 범위에서 발생합니다.
그것은 당신에게 달리기보다 많은 이점을 사지 않습니다
. $profile
& $profile
프로필을 새로로드하기 위해 작동합니다.
프로파일이 별명을 설정하거나 실패한 가져 오기를 실행하면 이전 프로파일의로드에서 이미 설정되었으므로 오류가 표시됩니다.
왜 이렇게하려고합니까?
복제물을 생성 할 가능성이 있기 때문에 ($ Env : Path에 추가) 및 오류를 일으키는 일정한/재시험 객체를 설정하는 데 문제가 발생할 수 있습니다.
최근 에이 주제에 대한 스레드가있었습니다 Microsoft.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 창을 올바른 디렉토리로 가져 가지 않았습니다. 나는 이것이 새로운 PowerShell 창의 컨텍스트에서 $ pwd가 평가되기 때문에 우리가 처리하기를 원하는 가치가 아니기 때문이라고 생각합니다.
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 fassett에게 감사드립니다.
몇 년 후이 문제를 발견했기 때문에 호출 연산자를 사용할 수 있다고 덧붙였습니다. &
기본 변수로 프로필을 프로필에로드하려면 다음과 같습니다. $profile
.
따라서 세션이 어떻게 든 프로필을로드하지 못하면 (CMDER/CONEMU로 나에게 발생) 유형을 입력하십시오.
& $profile