Remediere: Pornirea lentă a consolei PowerShell și a scripturilor

Am observat că, uneori, consola PowerShell durează mult până se deschide. Această problemă apare pe diferite computere. În unele cazuri, poate dura câteva minute până când PowerShell se încarcă. Acest lucru afectează deschiderea shell-ului de comandă în sine (powershell.exe sau pwsh.exe) și timpul de execuție al scripturilor PowerShell de conectare lansate prin GPO sau scripturi în sarcinile programate. Această postare explică cum să identifici motivele potențiale pentru pornirea lentă a PowerShell și cum să reduci timpul de încărcare.

Iată câteva motive comune pentru care PowerShell poate dura mult timp să se încarce:

  • Funcțiile definite de utilizator din fișierele de profil PowerShell sunt încărcate de fiecare dată când începe procesul PowerShell.exe
  • Un număr semnificativ de module PS sunt instalate și se încarcă automat
  • Modulul PSReadLine încarcă un fișier uriaș care conține istoricul comenzilor PowerShell
  • Încetinirile semnificative ale PowerShell și încărcarea modulelor sunt cauzate de conflicte sau corupție în componentele .NET Framework.

TheMăsura-Comandăcmdlet-ul poate fi utilizat pentru a măsura timpul de încărcare al unui proces PowerShell. Utilizați această comandă pentru a verifica timpul de încărcare a PowerShell în modul normal.:

powershell -noprofile -ExecutionPolicy Bypass ( Measure-Command { powershell "Write-Host 1" } ).TotalSeconds

Comanda va afișa cât de mult a durat procesul PowerShell pentru a încărca și executa o comandă simplă.

Când PowerShell pornește, poate raporta timpul necesar pentru încărcare.

Loading personal and system profiles took XXX ms

După cum puteți vedea în acest exemplu, procesul PowerShell a durat 12 secunde pentru a se încărca. Asta e destul de mult. Acest mesaj este afișat automat dacă timpul de încărcare a profilurilor PowerShelldepășește 500 ms.

Acest lucru sugerează că fișierele de profil PowerShell execută cod lent de fiecare dată când începe procesul.

Comparați viteza de pornire a procesului PowerShell atunci când profilurile nu sunt încărcate. Pentru a face acest lucru, rulați procesul shell cu-fara profilopţiune:

powershell.exe -noprofile

sau pentru a rula PowerShell Core:

Mai multe lecturi:Prompt de comandă Windows 10: Consolă nouă vs. Consolă veche

pwsh.exe -noProfile

După cum puteți vedea, PowerShell a pornit mult mai repede când profilurile nu au fost încărcate. Profilurile PowerShell sunt fișiere PS1 care sunt utilizate pentru a configura mediul utilizatorului. De asemenea, permit utilizatorului să ruleze anumite comenzi și să încarce funcții sau module personalizate.

În mod implicit, fișierele de profil PowerShell nu sunt utilizate (nu sunt create fișiere de profil). Următoarea comandă afișează o listă cu toate fișierele de profil care se vor încărca când începe procesul PowerShell.

$profile | select *

Verificați manual conținutul tuturor fișierelor de profil pentru utilizator sau utilizați următoarele comenzi pentru a le afișa:
Get-Content $PROFILE.AllUsersAllHosts
Get-Content $PROFILE.AllUsersCurrentHost
Get-Content $PROFILE.CurrentUserAllHosts
Get-Content $PROFILE.CurrentUserCurrentHost

În cazul meu, unele comenzi sunt adăugate laMicrosoft.PowerShell_profile.ps1fișier utilizator. Examinați fișierul de profil pentru a vă asigura că toate comenzile și funcțiile sunt necesare. Dacă este posibil, eliminați comenzile inutile și optimizați codul.

Un număr mare de module instalate ar putea fi un alt motiv posibil pentru pornirea lentă a PowerShell. PowerShell încarcă automat module din următoarele foldere:

C:Users%username%DocumentsWindowsPowerShellModules
C:Program FilesWindowsPowerShellModules
C:Windowssystem32WindowsPowerShellv1.0Modules

Lista lor poate fi afișată după cum urmează:

$Env:PSModulePath -split ';'

Listați modulele PS care au fost încărcate în sesiune.

Get-Module -ListAvailable

Listați modulele terțe instalate.

Get-InstalledModule

Verificați lista pentru a vedea dacă aveți nevoie de toate modulele. Dezinstalați orice module PowerShell neutilizate.:
Remove-Module -Name BurntToast
Uninstall-Module -Name BurntToast -AllVersions -Force

Modulele PowerShell instalate manual trebuie dezinstalate manual.

Pentru a analiza timpul de încărcare al fiecărui modul, utilizați următoarea comandă:

Measure-Command { Import-Module ModuleName -Force }

Sau verificați timpul de încărcare al tuturor modulelor PS în vrac:
$modules = Get-InstalledModule| Select-Object -ExpandProperty Name -Unique
foreach ($mod in $modules) {
$time = Measure-Command { Import-Module $mod -Force }
[PSCustomObject]@{
Module = $mod
LoadTimeSec = $time.Totalseconds
}
}

Vedeți care module durează cel mai mult pentru încărcare.

Pentru a preveni încărcarea automată a tuturor modulelor PS, adăugați următoarea linie la fișierul de profil:

$PSModuleAutoLoadingPreference="None"

În acest caz, puteți încărca manual modulul necesar utilizând următoarea comandă:

Import-Module [ModuleName]

Asigurați-vă că adăugați următoarele module comune la fișierul dvs. de profil:

Import-Module Microsoft.PowerShell.Utility
Import-Module Microsoft.PowerShell.Management

Există, de asemenea, o problemă cunoscută la încărcarea modulului VMware Infrastructure Management PowerShell, cunoscut și caVMware PowerCLI. Încărcarea modulului poate dura câteva minute pe un computer care nu este conectat la Internet. Problema este că, la încărcare, modulul încearcă să verifice o listă externă de certificate revocate (CRL,Lista de revocare a certificatelor). Din cauza lipsei de conectivitate la internet, acest proces a expirat. Soluția este sădezactivați verificarea CRL în Windows. Puteți dezactiva verificarea CRL prin intermediul registrului:

reg add HKLMSYSTEMCurrentControlSetServicesSstpSvcParameters /v NoCertRevocationCheck /t REG_DWORD /d 0x00000001 /f

Sau în appletul Internet Properties:inetcpl.cpl->Avansat–> debifați opțiuneaVerificați revocarea certificatului de editor (server)..

Motivul pentru care PowerShell poate dura mult timp pentru a porni este adesea software-ul antivirus care este instalat pe computer. Puteți verifica ce DLL-uri și module externe sunt încărcate când începe procesul PowerShell.

  1. Deschidecmd.exeși rulați comanda:powershell.exe -c "Write-Host $PID;Start-Sleep -s 60"
  2. Această comandă returnează ID-ul procesului (PID) al procesului PowerShell.exe care rulează. CopiațiPIDși inserați-l în următoarea comandă într-o nouă sesiune PowerShell:
    Get-Process | where {$_.Id -eq <YOUR_PID>} | select -ExpandProperty modules
  3. Veți primi o listă cu DLL-urile încărcate când începe procesul PowerShell. Verificați dacă biblioteca dvs. antivirus este listată. Dacă da, încercați să adăugați procesele pwsh.exe și powershell.exe la excepțiile antivirus.

De exemplu, puteți folosi comanda de mai jos pentru a adăuga excluderi la antivirusul Windows Defender încorporat:

Add-MpPreference -ExclusionProcess "C:WindowsSystem32WindowsPowerShellv1.0powershell.exe","C:Program FilesPowerShell7pwsh.exe"

Dacă bănuiți că pornirea lentă a PowerShell este cauzată de funcționarea lentă a bibliotecii .NET Framework, puteți compila toate ansamblurile utilizate în codul mașină nativ folosindngen.exeinstrument (Native Image Generator). Acest lucru va îmbunătăți semnificativ performanța aplicațiilor .NET, inclusiv PowerShell:

$env:PATH = [Runtime.InteropServices.RuntimeEnvironment]::GetRuntimeDirectory()
[AppDomain]::CurrentDomain.GetAssemblies() | ForEach-Object {
$path = $_.Location
if ($path) {
$name = Split-Path $path -Leaf
Write-Host -ForegroundColor Yellow "`r`nRunning ngen.exe on '$name'"
ngen.exe install $path /nologo
}
}

ClasiculMonitor de procesinstrumentul poate fi folosit și pentru a analiza timpul de pornire a PowerShell. (https://technet.microsoft.com/en-us/sysinternals/processmonitor.aspx). FugiProcMon64.exe, activați filtrul în procesul PowerShell.exe, deschideți shell-ul PS și identificați operațiunile care au cauzat cea mai mare întârziere.

În exemplul meu, citirea fișierului istoric al comenzilor PowerShell menținut de modulul PSReadline a durat aproximativ 30 de secunde. (C:UsersusernameAppDataRoamingMicrosoftWindowsPowerShellPSReadLineConsoleHost_history.txt). Problema a fost cauzată deConsoleHost_history.txtfișier care depășește 2 GB. Curățarea fișierului istoric a redus semnificativ timpul de pornire a PowerShell.

Related Posts