Powershell медленно запускается в Windows 10

Powershell медленно запускается в Windows 10

У меня возникла проблема с медленным запуском командной строки PowerShell в Windows 10 (версия 1703 - Creators Update).

Мои аппаратные характеристики (довольно быстрая машина): Intel i5-7440HQ (четырехъядерный) / 32 ГБ оперативной памяти DDR4 / жесткий диск Samsung SSD 512.

Я пробовал обойти политику профиля и выполнения, но это ничего не меняет:

powershell -noprofile -ExecutionPolicy Обход ( Measure-Command { powershell "Write-Host 1" } ).TotalSeconds

6,228067

На таком же ноутбуке моего друга с Windows 10 без Creators Update PowerShell запускается менее чем за 0,5 секунды.

Также пробовал сделать компиляцию с помощью ngen.exe, но это не помогло:

$env:path = [Runtime.InteropServices.RuntimeEnvironment]::GetRuntimeDirectory()
[AppDomain]::CurrentDomain.GetAssemblies() | % {
  if (! $_.location) {continue}
  $Name = Split-Path $_.location -leaf
  Write-Host -ForegroundColor Yellow "NGENing : $Name"
  ngen install $_.location | % {"`t$_"}
}

Есть идеи, как я могу исследовать эту проблему?

Привет

решение1

Это происходило и со мной - хотя, возможно, не лучшим образом, добавляя powershell.exeк спискуИсключения Защитника Windowsускорил его с 20 секунд до <1 секунды.

Использование устаревшей консоли, очистка PSReadLine и запуск ngen, похоже, вообще не помогли.

решение2

Я сталкивался с той же проблемой довольно долгое время, пока PowerShell не начал давать сбой при запуске со следующей ошибкой:

Exception:
System.OutOfMemoryException: Array dimensions exceeded supported range.
   at System.Collections.Generic.List`1.set_Capacity(Int32 value)
   at System.Collections.Generic.List`1.EnsureCapacity(Int32 min)
   at System.Collections.Generic.List`1.Add(T item)
   at System.IO.File.InternalReadAllLines(String path, Encoding encoding)
   at Microsoft.PowerShell.PSConsoleReadLine.<ReadHistoryFile>b__67_0()
   at Microsoft.PowerShell.PSConsoleReadLine.WithHistoryFileMutexDo(Int32 timeout, Action action)
   at Microsoft.PowerShell.PSConsoleReadLine.DelayedOneTimeInitialize()
   at Microsoft.PowerShell.PSConsoleReadLine.Initialize(Runspace runspace, EngineIntrinsics engineIntrinsics)
   at Microsoft.PowerShell.PSConsoleReadLine.ReadLine(Runspace runspace, EngineIntrinsics engineIntrinsics)
-----------------------------------------------------------------------

Это привело меня к существующей проблеме на Github:https://github.com/Powershell/PSReadLine/issues/673

Я попробовал удалить файл истории, ~\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadline\который к тому времени был размером более 6 ГБ, и после этого консоль PowerShell начала открываться довольно быстро.

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

решение3

Могут быть и другие причины медленного запуска Powershell, но есть одна, которая...всегдаДля меня причиной замедления является обновление Windows.

Вместо того, чтобы запускать ngenкаждую сборку, которую случайно загрузил PowerShell, я хочу запустить команду, ngen updateкоторая оптимизирует каждую глобально установленную сборку:

. (Join-Path ([Runtime.InteropServices.RuntimeEnvironment]::GetRuntimeDirectory()) ngen.exe) update

После обновления до Win10 за май 2019 года я вижу, что производительность улучшилась

(measure-command { powershell.exe -command "1+1" }).TotalSeconds

от ~1,35 с до ~0,55 с.

решение4

После анализа powershell.exe с помощью procmon (инструмент sysinternals) я увидел, что процесс пытался что-то сделать в папке catroot2, поэтому после переименования (вам нужно остановить службу CryptSvc, которая блокирует папку) она была создана автоматически. Поэтому вывод таков: папка была повреждена. (Извините за мой плохой английский)

Выполнить следующий .bat

net stop CryptSvc /y
rename c:\windows\system32\catroot2 Catroot2.bak
net start CryptSvc

Связанный контент