Domanda

Voglio ricaricare il mio profilo utente da un file di script. Ho pensato che puntino approvvigionamento dall'interno del file di script farebbe il trucco, ma non funziona:

# file.ps1
. $PROFILE

Tuttavia, esso funziona se ho puntini sulle fonte da interprete di PowerShell.

Perché voglio fare questo?

ho eseguito questo script ogni volta che aggiorno il mio profilo e voglio provarlo, quindi mi piacerebbe evitare di dover riavviare PowerShell per aggiornare l'ambiente.

È stato utile?

Soluzione

Quindi, l'approccio che hai segnato come la risposta può funzionare all'interno del prompt dei comandi PowerShell, ma non funziona all'interno PowerShell ISE (che, per me, offre una sessione di PowerShell superiore) e probabilmente non funzionerà proprio nel altri ambienti PowerShell.

Ecco uno script che ho usato per un po ', e ha funzionato molto bene per me in ogni ambiente. Ho semplicemente messo questa funzione nel mio Profile.ps1 a ~ \ Documenti \ WindowsPowerShell, e ogni volta che voglio ricaricare il mio profilo, ho DOT-fonte la funzione, cioè.

. Reload-Profile

Ecco la funzione:

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

Altri suggerimenti

Se si vuole globalmente aggiornare il proprio profilo da uno script, si dovrà eseguire lo script "dot-sourced".

Quando si esegue lo script, tutto lo script profilo viene eseguito in un ambito di "script" e non modificare la portata "globale".

Al fine di uno script per modificare la portata globale, ha bisogno di essere "dot-source" o preceduto con un punto.

. ./yourrestartscript.ps1

dove hai il tuo profilo script "dot-sourced" all'interno di "yourrestartscript.ps1". Che cosa si sta effettivamente facendo è dire "yourrestartscript" per eseguire nell'ambito corrente e dentro lo script, si indica lo script profilo $ per l'esecuzione in ambito dello script. Dal campo di applicazione della sceneggiatura è la portata globale, tutte le variabili impostate o comandi nel tuo profilo accadrà in ambito globale.

Questo non ti comprare molto vantaggio rispetto esecuzione

. $profile
& $profile   

lavora per ricaricare il profilo.

Se il tuo profilo setta alias o esegue le importazioni che non riescono poi si vedrà gli errori perché erano già impostati nel caricamento precedente del profilo.

Perché si sta cercando di fare questo?

Perché è probabile che creare duplicati (aggiunge a $ env: path). E problemi con la creazione di oggetti costanti / sola lettura che causano errori

C'è stato un thread su questo argomento di recente su microsoft.public.windows.powershell

Se si sta tentando di ripristinare lo stato della sessione non c'è modo per fare questo, anche utilizzando un ambito interno ($host.EnterNestedPrompt()) a causa della possibilità di impostare le variabili / alias / ... a "tutte le possibilità".

Ho trovato questa soluzione:

#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 versione più elaborata:

#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

Questa è solo una raffinatezza dello script due linee in risposta guillermooo cui sopra, che non ha ottenuto la nuova finestra di PowerShell nella directory corretta per me. Credo che questo è dovuto al fatto $ PWD viene valutata nel contesto della nuova finestra di PowerShell, che non è il valore che vogliamo set-location per l'elaborazione.

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

Per i diritti non dovrebbe funzionare, come la linea di comando sputa fuori è corretto, ma sembra di fare il lavoro e che è abbastanza buono per me.

Ho usato questo per risolvere quello profilo stava prendendo sempre al carico.

Start Run:

powershell_ise -noprofile

Poi mi sono imbattuto in questo modo:

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

Grazie @Winston Fassett per avermi più vicino a trovare il mio problema.

da quando sono imbattuti in questo diversi anni più tardi, ho pensato di aggiungere che è possibile utilizzare l'operatore invocazione: & per caricare il tuo profilo con la variabile predefinita per il tuo profilo. $profile

così, se la sessione non riesce in qualche modo a caricare il profilo (succede a me con cmder / conemu) digitare semplicemente:

& $profile

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top