Как перезагрузить профиль пользователя из файла скрипта в PowerShell - PullRequest
37 голосов
/ 20 февраля 2009

Я хочу перезагрузить свой профиль пользователя из файла скрипта. Я думал, что точечный источник из файла скрипта поможет, но он не работает:

# file.ps1
. $PROFILE

Однако, это работает, если я укажу источник из интерпретатора PowerShell.

Почему я хочу это сделать?

Я запускаю этот скрипт каждый раз, когда обновляю свой профиль и хочу его протестировать, поэтому я бы хотел избежать перезапуска PowerShell для обновления среды.

Ответы [ 7 ]

28 голосов
/ 20 февраля 2009

Если вы хотите глобально обновить свой профиль из сценария, вам придется запустить этот сценарий "с точечным источником".

Когда вы запускаете ваш скрипт, все скрипты профиля запускаются в «скриптовой» области и не изменяют вашу «глобальную» область.

Чтобы скрипт мог изменить вашу глобальную область видимости, он должен быть «точечным источником» или иметь точку.

. ./yourrestartscript.ps1

где у вас есть сценарий вашего профиля "с точечным источником" внутри "yourrestartscript.ps1". Что вы на самом деле делаете, так это говорите «yourrestartscript» для запуска в текущей области действия, а внутри этого сценария вы говорите сценарию $ profile для запуска в области действия сценария. Поскольку область действия сценария является глобальной областью действия, любые переменные или команды в вашем профиле будут выполняться в глобальной области действия.

Это не дает вам большого преимущества перед бегом

. $profile
26 голосов
/ 31 марта 2011

Таким образом, подход, который вы отметили как ответ, может работать в командной строке Powershell, но он не работает в PowerShell ISE (который, на мой взгляд, обеспечивает превосходный сеанс PowerShell) и, вероятно, не будет работать правильно в другие среды PowerShell.

Вот сценарий, который я использовал некоторое время, и он работал очень хорошо для меня в любой среде. Я просто помещаю эту функцию в свой Profile.ps1 в ~ \ Documents \ WindowsPowerShell, и всякий раз, когда я хочу перезагрузить свой профиль, я поставляю точечный источник функции, т.е.

. Reload-Profile

Вот функция:

function Reload-Profile {
    @(
        $Profile.AllUsersAllHosts,
        $Profile.AllUsersCurrentHost,
        $Profile.CurrentUserAllHosts,
        $Profile.CurrentUserCurrentHost
    ) | % {
        if(Test-Path $_){
            Write-Verbose "Running $_"
            . $_
        }
    }    
}
5 голосов
/ 16 января 2014
& $profile   

работает для перезагрузки профиля.

Если ваш профиль устанавливает псевдонимы или выполняет импорт, который завершается неудачей, вы увидите ошибки, поскольку они уже были установлены при предыдущей загрузке профиля.

3 голосов
/ 20 февраля 2009

Почему вы пытаетесь это сделать?

Поскольку он может создавать дубликаты (добавляет $ env: path) и проблемы с установкой постоянных / только для чтения объектов, вызывающих ошибки.

Недавно была тема по этой теме на microsoft.public.windows.powershell .

Если вы пытаетесь сбросить состояние сеанса, это невозможно сделать, даже используя внутреннюю область видимости ($host.EnterNestedPrompt()) из-за возможности устанавливать переменные / псевдонимы / ... в "всей области видимости" .

2 голосов
/ 20 февраля 2009

Я нашел этот обходной путь:

#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
0 голосов
/ 12 июня 2018

поскольку я наткнулся на это несколько лет спустя, я подумал добавить, что вы можете использовать оператор вызова: & для загрузки вашего профиля с переменной по умолчанию в ваш профиль: $profile.

Итак, если ваша сессия как-то не загружает ваш профиль (происходит со мной с помощью cmder / conemu), просто наберите:

& $profile

0 голосов
/ 07 июля 2009

Это только уточнение двухстрочного скрипта в ответе guillermooo выше, который не привел новое окно 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
}

По праву это не должно работать, так как выпадающая командная строка искажена, но, похоже, она справляется, и для меня этого достаточно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...