Comment recharger le profil de l'utilisateur à partir du fichier script PowerShell

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

  •  05-09-2019
  •  | 
  •  

Question

Je veux recharger mon profil d'utilisateur à partir d'un fichier de script. Je pensais que point l'approvisionnement de l'intérieur du fichier script ferait l'affaire, mais il ne fonctionne pas:

# file.ps1
. $PROFILE

Toutefois, il ne fonctionne que si je les points sur la source à partir de l'interpréteur de PowerShell.

Pourquoi est-ce que je veux faire?

Je lance ce script chaque fois que je mets à jour mon profil et que vous souhaitez le tester, donc je voudrais éviter d'avoir à redémarrer PowerShell pour rafraîchir l'environnement.

Était-ce utile?

La solution

Ainsi, l'approche que vous avez marqué que la réponse peut travailler à l'intérieur de l'invite de commande Powershell, mais il ne fonctionne dans PowerShell ISE (qui, pour moi, offre une session de PowerShell supérieure) et ne fonctionnera probablement pas pas droit d'autres environnements PowerShell.

Voici un script que je l'ai utilisé pendant un certain temps, et il a travaillé très bien pour moi dans tous les environnements. Je mets simplement cette fonction dans mon Profile.ps1 à ~ \ Documents \ WindowsPowerShell, et chaque fois que je veux recharger mon profil, je point-source de la fonction, i.e..

. Reload-Profile

Voici la fonction:

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

Autres conseils

Si vous voulez rafraîchir globalement votre profil à partir d'un script, vous devrez exécuter ce script « dot-traité ».

Lorsque vous exécutez votre script, tout le script de profil exécute dans un champ « script » et ne modifiera pas votre portée « globale ».

Pour un script pour modifier votre portée globale, il doit être « point-source » ou précédé d'une période.

. ./yourrestartscript.ps1

où vous avez votre script de profil « dot-source » à l'intérieur de « yourrestartscript.ps1 ». Ce que vous faites est en fait dire « yourrestartscript » pour exécuter dans le périmètre actuel et à l'intérieur de ce script, vous informe que le script de profil $ pour exécuter dans le périmètre du script. Étant donné que la portée du script est la portée globale, toutes les variables définies ou des commandes dans votre profil se produiront dans la portée globale.

Cela ne vous achetez pas beaucoup d'avantage sur l'exécution

. $profile
& $profile   

fonctionne pour recharger le profil.

Si votre profil définit des alias ou exécute les importations qui ne parviennent alors vous verrez des erreurs parce qu'ils étaient déjà définies dans le chargement précédent du profil.

Pourquoi vous essayez de le faire?

Parce qu'il est susceptible de créer des doublons (à env concatène $: chemin). Et des problèmes avec la mise en objets constants / readonly provoquant des erreurs

Il y avait un fil sur ce sujet récemment sur microsoft.public.windows.powershell

Si vous essayez de réinitialiser l'état de la session, il n'y a aucun moyen de le faire, même en utilisant une portée intérieure ($host.EnterNestedPrompt()) en raison de la possibilité de définir des variables / alias / ... à « toute portée ».

J'ai trouvé cette solution de contournement:

#some-script.ps1

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

Une version plus élaborée:

#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

Ceci est seulement un raffinement des deux script de ligne dans la réponse de guillermooo ci-dessus, qui n'a pas obtenu la nouvelle fenêtre PowerShell dans le répertoire correct pour moi. Je crois que c'est parce que $ PWD est évalué dans le contexte de la nouvelle fenêtre PowerShell, ce qui est la valeur que nous voulons mettre en-lieu de traiter.

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

Par les droits, il ne doit pas travailler, comme la ligne de commande, il recrache est malformé, mais il semble faire le travail et c'est assez bon pour moi.

J'ai utilisé ce pour résoudre ce profil prenait une éternité à charger.

Démarrer Exécuter:

powershell_ise -noprofile

Alors je couru ceci:

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

Merci @Winston Fassett pour moi se rapprocher de trouver ma question.

depuis que je suis tombé sur cette quelques années plus tard, je pensais à ajouter que vous pouvez utiliser l'opérateur d'invocation: & pour charger votre profil avec la variable par défaut à votre profil. $profile

, si votre session échoue en quelque sorte à charger votre profil (qui me arrive avec cmder / conemu) il suffit de taper:

& $profile

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top