Pergunta

Eu quero recarregar meu perfil de usuário de um arquivo script. Eu pensei que salpicam terceirização-lo de dentro do arquivo script seria fazer o truque, mas ele não funciona:

# file.ps1
. $PROFILE

No entanto, ela não funciona se eu dot Fonte lo do intérprete de PowerShell.

Por que eu quero fazer isso?

Eu executar este script cada vez que eu atualizar meu perfil e quiser testá-lo, então eu gostaria de evitar ter de reiniciar PowerShell para refrescar o ambiente.

Foi útil?

Solução

Assim, a abordagem que você marcado como a resposta pode trabalhar dentro do comando PowerShell pronta, mas ele não funciona dentro PowerShell ISE (que, para mim, fornece uma sessão PowerShell Superior) e, provavelmente, não vai funcionar bem no ambientes outra PowerShell.

Aqui está um script que tenho vindo a utilizar durante algum tempo, e tem funcionado muito bem para mim em todos os ambientes. Eu simplesmente colocar esta função em meu Profile.ps1 em ~ \ Documents \ WindowsPowerShell, e sempre que eu quiser recarregar meu perfil, eu dot-fonte da função, ou seja.

. Reload-Profile

Aqui está a função:

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

Outras dicas

Se você quiser atualizar globalmente o seu perfil a partir de um script, você terá que executar esse script "ponto de origem".

Quando você executar o script, todos os script de perfil é executado em um escopo "script" e não vai modificar o seu alcance "global".

Para que um script para modificar o seu alcance global, ele precisa ser "dot-source" ou precedido por um ponto.

. ./yourrestartscript.ps1

, onde você tem o seu script de perfil "ponto de origem" dentro de "yourrestartscript.ps1". O que você está realmente fazendo é dizer "yourrestartscript" para executar no escopo atual e dentro desse script, você está dizendo ao script de perfil $ para executar no escopo do script. Desde âmbito do script é o escopo global, quaisquer variáveis ??definir ou comandos em seu perfil vai acontecer no âmbito global.

Isso não comprar-lhe muita vantagem sobre correr

. $profile
& $profile   

funciona para recarregar o perfil.

Se o seu perfil conjuntos aliases ou executa as importações que falham, então você vai ver erros porque eles já foram definidos no carregamento prévio do perfil.

Por que você está tentando fazer isso?

Porque é susceptível de criar duplicatas (acrescenta a $ env: caminho). E problemas com a definição constante / readonly objetos causando erros

Houve uma discussão sobre este tema recentemente em microsoft.public.windows.powershell

Se você está tentando redefinir o estado da sessão não há nenhuma maneira de fazer isso, mesmo usando um escopo interno ($host.EnterNestedPrompt()) por causa da capacidade de definir variáveis ??/ aliases / ... a "todas as possibilidades".

Eu encontrei esta solução alternativa:

#some-script.ps1

#restart profile (open new powershell session)
cmd.exe /c start powershell.exe -c { Set-Location $PWD } -NoExit
Stop-Process -Id $PID

Uma versão mais elaborada:

#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

Este é apenas um refinamento do script duas linhas em resposta de guillermooo acima, que não chegou a nova janela do PowerShell para o diretório correto para mim. Eu acredito que este é porque $ PWD é avaliada no contexto novo da janela do PowerShell, que não é o valor que queremos set-location para processo.

function Restart-Ps {
$cline = "`"/c start powershell.exe -noexit -c `"Set-Location '{0}'" -f $PWD.path
cmd $cline
Stop-Process -Id $PID
}

Por direito ele não deve trabalhar, como a linha de comando ele cospe é mal formado, mas parece fazer o trabalho e isso é bom o suficiente para mim.

Eu usei isso para solucionar problemas que o perfil foi levando uma eternidade para carregar.

Iniciar Run:

powershell_ise -noprofile

Então eu corri o seguinte:

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

Obrigado @Winston Fassett para mim ficando mais perto de encontrar o meu problema.

desde que eu hospedaria este alguns anos mais tarde, eu pensei de acrescentar que você pode usar o operador de invocação: & para carregar o seu perfil com a variável padrão para o seu perfil:. $profile

Então, se a sua sessão de alguma forma não consegue carregar o seu perfil (me acontece com cmder / conemu) basta digitar:

& $profile

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top