Cómo volver a cargar el perfil de usuario del archivo de secuencia de comandos en PowerShell

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

  •  05-09-2019
  •  | 
  •  

Pregunta

Quiero volver a cargar perfil de usuario desde un archivo de script. Pensé que puntos de abastecimiento desde dentro del archivo de script que hacer el truco, pero no funciona:

# file.ps1
. $PROFILE

Sin embargo, no funciona si punteo fuente él desde el intérprete de PowerShell.

¿Por qué quiero hacer esto?

Ejecutar este proceso cada vez que se actualiza el perfil y quiero probarlo, así que me gustaría evitar tener que reiniciar PowerShell para refrescar el ambiente.

¿Fue útil?

Solución

Por lo tanto, el enfoque que ha marcado como la respuesta puede trabajar dentro de la línea de comandos de PowerShell, pero no funciona en el interior PowerShell ISE (que, para mí, proporciona una sesión de PowerShell superiores) y probablemente no funcionará en pleno otros entornos PowerShell.

Aquí hay un script que he estado usando durante un tiempo, y ha funcionado muy bien para mí en todos los ambientes. Simplemente ponga esta función en mi Profile.ps1 en ~ \ documentos \ WindowsPowerShell, y siempre que lo desee para recargar mi perfil, punto-fuente de la función, es decir.

. Reload-Profile

Esta es la función:

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

Otros consejos

Si desea actualizar su perfil de forma global a partir de una secuencia de comandos, tendrá que ejecutar el guión "punto de origen".

Cuando se ejecuta la secuencia de comandos, toda la secuencia de comandos se ejecuta en un perfil "guión" alcance y no modificará su alcance "global".

Para que una secuencia de comandos para modificar su alcance global, que tiene que ser "punto de origen" o precedido con un punto.

. ./yourrestartscript.ps1

donde tiene su script de perfil dentro de "punto de origen" de "yourrestartscript.ps1". Lo que está haciendo en realidad está diciendo "yourrestartscript" para ejecutar en el ámbito actual y dentro de ese guión, le está diciendo al script de perfil $ para funcionar en el alcance del guión. Dado el alcance de la secuencia de comandos es el alcance global, las variables establecidas o comandos en su perfil que sucederá en el ámbito global.

Eso no te compran mucha ventaja de rueda

. $profile
& $profile   

funciona para recargar el perfil.

Si su perfil establece alias o ejecuta importaciones que fallan, podrá ver los errores debido a que ya se habían establecido en la carga previa del perfil.

¿Por qué estás tratando de hacer esto?

Debido a que es probable que crear duplicados (anexa a $ env: path). Y los problemas con la configuración de objetos constantes de sólo lectura / causando errores

Hubo un hilo sobre este tema recientemente en microsoft.public.windows.powershell

Si usted está tratando de restablecer el estado de la sesión no hay manera de hacer esto, incluso utilizando un ámbito interno ($host.EnterNestedPrompt()) debido a la capacidad para establecer las variables / alias / ... a "toda alcance".

He encontrado esta solución:

#some-script.ps1

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

Una versión más 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

Esto es sólo un refinamiento de la escritura de dos líneas en la respuesta de guillermooo arriba, que no recibieron la nueva ventana de PowerShell en el directorio correcto para mí. Creo que esto se debe a $ PWD se evalúa en el contexto de la nueva ventana de PowerShell, que no es el valor que queremos establecer en la ubicación para procesar.

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

Por los derechos para que no funcione, ya que la línea de comandos que escupe tienen un formato incorrecto, pero parece que para hacer el trabajo, y eso es suficiente para mí.

He utilizado este perfil para solucionar lo que se tarda mucho en cargar.

Ejecutar:

powershell_ise -noprofile

Entonces me encontré con esto:

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

Gracias @Winston Fassett por conseguirme más cerca de encontrar mi problema.

ya había tropezado con esta varios años más tarde, pensé que añadir que se puede utilizar el operador de invocación: & para cargar su perfil con la variable por defecto a su perfil:. $profile

Por lo tanto, si su sesión de alguna manera no se puede cargar su perfil (que me pasa con cmder / conemu) sólo tiene que escribir:

& $profile

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top