programing

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

lastmoon 2023. 8. 5. 10:52
반응형

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

스크립트 파일에서 사용자 프로필을 다시 로드합니다.스크립트 파일 내에서 도트 소스를 사용하면 효과가 있을 것이라고 생각했지만, 효과가 없었습니다.

# file.ps1
. $PROFILE

그러나 PowerShell의 인터프리터에서 점 소스를 사용하면 작동합니다.

내가 왜 이걸 하고 싶은 거지?

프로필을 업데이트할 때마다 이 스크립트를 실행하고 테스트를 수행하기 때문에 환경을 새로 고치기 위해 PowerShell을 다시 시작하지 않아도 됩니다.

스크립트에서 프로필을 전체적으로 새로 고치려면 해당 스크립트 "도트 소스"를 실행해야 합니다.

스크립트를 실행할 때 모든 프로파일 스크립트는 "스크립트" 범위에서 실행되며 "글로벌" 범위는 수정되지 않습니다.

스크립트가 전역 범위를 수정하려면 "점 소스"이거나 마침표가 선행되어야 합니다.

. ./yourrestartscript.ps1

여기서 "다시 시작 스크립트.ps1"의 내부에 프로필 스크립트 "도트"가 있습니다.당신이 실제로 하고 있는 것은 "다시 시작 스크립트"가 현재 범위에서 실행되도록 지시하는 것이고, 그 스크립트 안에서 $profile 스크립트가 스크립트의 범위에서 실행되도록 지시하는 것입니다.스크립트의 범위가 전역 범위이므로 프로파일의 변수 집합 또는 명령은 전역 범위에서 발생합니다.

그것은 당신이 달리는 것보다 많은 이점을 살 수 없습니다.

. $profile

따라서 답변으로 표시한 접근 방식은 Powershell 명령 프롬프트 내에서 작동할 수 있지만 PowerShell ISE 내에서는 작동하지 않으며(나에게는 뛰어난 PowerShell 세션을 제공함) 다른 PowerShell 환경에서는 제대로 작동하지 않을 수도 있습니다.

여기 제가 한동안 사용했던 스크립트가 있습니다. 모든 환경에서 잘 작동했습니다.이 함수를 Profile.ps1의 ~\Documents\에 넣기만 하면 됩니다.Windows PowerShell 및 프로필을 다시 로드하고 싶을 때마다 함수를 닷 소스로 만듭니다.

. Reload-Profile

기능은 다음과 같습니다.

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

프로파일을 다시 로드합니다.

프로파일에서 별칭을 설정하거나 가져오기를 실행했지만 실패하면 프로파일의 이전 로드에서 이미 설정된 오류가 표시됩니다.

왜 이러는 거예요?

중복 항목($env:path에 추가됨)이 생성될 가능성이 높고 상수/읽기 전용 개체 설정 문제로 인해 오류가 발생할 수 있습니다.

최근에 microsoft.public에 이 주제에 대한 스레드가 있었습니다.창문파워셸

의 상태를 재설정하려고 , 할 .$host.EnterNestedPrompt()변수를 " 범위에서 할 수 있는 입니다.) /수aliases.../...를 "모든 범위"에서 설정할 수 있기 때문입니다.

다음과 같은 해결 방법을 찾았습니다.

#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

이것은 위의 Guilleroo의 답변에 있는 두 줄 스크립트를 개선한 것일 뿐, 새로운 PowerShell 창을 올바른 디렉토리로 가져오지 못했습니다.$PWD가 새로운 PowerShell 창의 컨텍스트에서 평가되기 때문이라고 생각합니다. 이는 우리가 set-location에서 처리하기를 원하는 값이 아닙니다.

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 Fasset님께서 제 문제를 찾는 데 더 가까이 다가가게 해주셔서 감사합니다.

유사 별칭(키 시뮬레이션)

콘솔의 별칭처럼 기능을 사용하려면 키 누르기를 시뮬레이션하여 도트 소스를 사용해야 합니다.

# when "reload" is typed in the terminal, the profile is reloaded
# use sendkeys to send the enter key to the terminal
function reload {
    Add-Type -AssemblyName System.Windows.Forms
    [System.Windows.Forms.SendKeys]::SendWait(". $")
    [System.Windows.Forms.SendKeys]::SendWait("PROFILE")
    [System.Windows.Forms.SendKeys]::SendWait("{ENTER}")
}

그것이 작동하는 스크린샷

언급URL : https://stackoverflow.com/questions/567650/how-to-reload-user-profile-from-script-file-in-powershell

반응형