PowerShell에서 스크립트 파일에서 사용자 프로필을 다시로드하는 방법

StackOverflow https://stackoverflow.com/questions/567650

  •  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

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top