Correction: Démarrage lent de la console et scripts PowerShell

/fr/images/powershell-console-takes-30-second-to-open.png

J’ai remarqué que la console PowerShell met parfois beaucoup de temps à ouvrir. Ce problème se produit sur différents ordinateurs. Dans certains cas, il peut prendre plusieurs minutes pour que PowerShell se charge. Cela affecte l’ouverture du shell de commande lui-même (PowerShell.exe ou Pwsh.exe) et le temps d’exécution des scripts PowerShell Logon Lancé via GPO ou scripts dans les tâches planifiées. Cet article explique comment identifier les raisons potentielles du démarrage lent PowerShell et réduire le temps de chargement.

Voici quelques raisons courantes pour lesquelles PowerShell peut prendre beaucoup de temps à charger:

  • Les fonctions définies par l’utilisateur dans les fichiers de profil PowerShell sont chargées chaque fois que le processus PowerShell.exe démarre

  • Un nombre significatif de modules PS est installé et se charge automatiquement

  • Le module PSReadline charge un énorme fichier contenant l’historique des commandes PowerShell

  • Des ralentissements significatifs dans le chargement PowerShell et les modules sont causés par des conflits ou une corruption dans les composants de framework.

L’attaque de commande de mesure peut être utilisée pour mesurer le temps de chargement d’un processus PowerShell. Utilisez cette commande pour vérifier le temps de chargement de PowerShell en mode normal::

PowerShell-Noprofile-ExecutionPolicy Bypass (Mesure-Command {PowerShell" Write-Host 1 "}) .TotalSeconds

/fr/images/powershell-console-takes-30-second-to-open.png

La commande affichera combien de temps il a fallu au processus PowerShell pour charger et exécuter une commande simple.

Lorsque PowerShell commence, cela peut signaler le temps qu’il a fallu pour charger.


Loading personal and system profiles took XXX ms

/fr/images/message-in-powershell-loading-personal-and-system.png

Comme vous pouvez le voir dans cet exemple, le processus PowerShell a pris 12 secondes à charger. C’est beaucoup. Ce message s’affiche automatiquement si le temps de chargement des profils PowerShell dépasse 500 ms.

Cela suggère que les fichiers de profil PowerShell exécutent du code lent chaque fois que le processus démarre.

Comparez la vitesse de démarrage du processus PowerShell lorsque les profils ne sont pas chargés. Pour ce faire, exécutez le processus Shell avec l’option de Noprofile:

«PowerShell.exe-Noprofile»

ou pour exécuter le noyau PowerShell:

`pwsh.exe-noprofile '

/fr/images/run-powershell-without-loading-profiles.png

Comme vous pouvez le voir, PowerShell a commencé beaucoup plus rapidement lorsque les profils n’étaient pas chargés. Les profils PowerShell sont des fichiers PS1 utilisés pour configurer l’environnement utilisateur. Ils permettent également à l’utilisateur d’exécuter des commandes spécifiques et de charger des fonctions ou des modules personnalisés.

Par défaut, les fichiers de profil PowerShell ne sont pas utilisés (aucun fichier de profil n’est créé). La commande suivante affiche une liste de tous les fichiers de profil qui se chargera lorsque le processus PowerShell démarre.

$ Profil | Sélectionner *

/fr/images/list-powershell-profiles.png

Vérifiez manuellement le contenu de tous les fichiers de profil pour l’utilisateur ou utilisez les commandes suivantes pour les afficher:

`Get-Content $ Profil.AllusersAllhosts

Get-content $ profil.alluserscurrenthost

Get-content $ profil.currentUserAllHosts

Get-content $ profil.CurrentUserCurrenthost `

Dans mon cas, certaines commandes sont ajoutées au fichier utilisateur Microsoft.Powershell_Profile.ps1. Passez en revue le fichier de profil pour vous assurer que toutes les commandes et fonctions sont nécessaires. Si possible, supprimez les commandes inutiles et optimisez le code. /fr/images/list-used-powershell-profile-files.png

Un grand nombre de modules installés pourraient être une autre raison possible du démarrage lent de PowerShell. PowerShell charge automatiquement des modules à partir des dossiers suivants:


C:\Users\%username%\Documents\WindowsPowerShell\ModulesC:\Program Files\WindowsPowerShell\ModulesC:\Windows\system32\WindowsPowerShell\v1.0\Modules

Leur liste peut être affichée comme suit:

`$ Env: psmodulepath-split ‘;’ '

/fr/images/list-used-ps-module-paths.png

Énumérez les modules PS qui ont été chargés dans la session.

«Get-module-listavailable»

Énumérez les modules tiers installés.

`Get-installedModule '

/fr/images/get-installedmodule.png

Consultez la liste pour voir si vous avez besoin de tous les modules. Désinstaller tout module PowerShell inutilisé.:

`Retirez le nom de module Burnttoast

Désinstallation-module-nom Burnttoast-alversions-force `

Pour analyser le temps de chargement de chaque module, utilisez la commande suivante:

Measure-Command {import-module modulename-force}

Ou vérifiez le temps de chargement de tous les modules PS en vrac:

`$ modules = get-stalledModule | Select-object-expandproperty name-Unique

foreach ($ mod in $ modules) {

$ time = mesure-command {import-module $ mod-force}

PSCustomObject @ {

Module = $ mod

LoadTimesec = $ time.totalsecondes

}

} `

/fr/images/measure-powershell-module-load-time.png

Voir quels modules prennent le plus de temps à charger.

Pour empêcher tous les modules PS de se charger automatiquement, ajoutez la ligne suivante au fichier de profil:

`$ PsmoduleAutoloAdingPreference = ‘Aucun’ '

Dans ce cas, vous pouvez charger manuellement le module requis à l’aide de la commande suivante:

Import-module modulename

Assurez-vous d’ajouter les modules communs suivants à votre fichier de profil:

`Import-module Microsoft.Powershell.utilité

Module d’importation Microsoft.Powershell.management `

Il existe également un problème connu lors du chargement du module PowerShell de gestion de l’infrastructure VMware, également connu sous le nom de VMware PowerCLI. Le module peut prendre plusieurs minutes à charger sur un ordinateur qui n’est pas connecté à Internet. Le problème est que, lors du chargement, le module essaie de vérifier une liste externe de certificats révoqués (CRL, liste de révocation des certificats). En raison d’un manque de connectivité Internet, ce processus a expiré. La solution consiste à désactiver la vérification du CRL sous Windows. Vous pouvez désactiver la vérification du CRL via le registre:

reg add hklm \ system \ currentControlset \ Services \ sstpsvc \ paramètres / v NOCERTREVOCAYCHECK / T REG\_DWORD / D 0x00000001 / F

Ou dans Internet Properties Applet: IneTCPL.cpl -> Advanced -> Uptick the Option Vérifier la révocation du certificat Publisher (Server).

/fr/images/disable-checking-for-publisher-server-certificat.png

La raison pour laquelle PowerShell peut prendre beaucoup de temps pour commencer est souvent le logiciel antivirus installé sur l’ordinateur. Vous pouvez vérifier les DLL et modules externes sont chargés lorsque le processus PowerShell démarre.

  1. Ouvrir cmd.exe 'et exécuter la commande: PowerShell.exe-c “Write-Host $ pid; start-sleep-s 60” `

  2. Cette commande renvoie l’ID de processus (PID) du processus PowerShell.exe en cours d’exécution. Copier le

Piquer

Et collez-le dans la commande suivante dans une nouvelle session PowerShell:

Get-Process | où {$ \_. id-eq } | Modules de sélection-expandPandProperty

  1. Vous recevrez une liste des DLL chargés au début du processus PowerShell. Vérifiez si votre bibliothèque antivirus est répertoriée. Si c’est le cas, essayez d’ajouter les processus pwsh.exe et powershell.exe à vos exceptions antivirus. /fr/images/list-dlls-loaded-when-the-powershell-process-start.png

Par exemple, vous pouvez utiliser la commande ci-dessous pour ajouter des exclusions à l’antivirus Windows Defender intégré:

Add-Mppreference-ExlusionProcess" C: \ Windows \ System32 \ Windowspowershell \ V1.0 \ PowerShell.exe "," C: \ Program Files \ PowerShell \ 7 \ Pwsh.exe "

Si vous soupçonnez que le démarrage lent de PowerShell est causé par le fonctionnement de la bibliothèque Slow.NET Framework, vous pouvez compiler tous les assemblages utilisés en code machine natif à l’aide de l’outil `ngen.exe ‘(générateur d’image natif). Cela améliorera considérablement les performances des applications.NET, y compris PowerShell:

`$ env: path = runtime.interopservices.runtimeenvironment :: getRuntimeDirectory ()

AppDomain :: currentDomain.getAssemblies () | Foreach-object {

$ path = $ _. Emplacement

if ($ path) {

$ name = Split-Path $ Path-Leaf

Écriture-host-foregroundcolor jaune “ rnrunning ngen.exe sur ‘$ name’ “ngen.exe installer $ path / nologo

}

} `

/fr/images/ngen-exe-regenerates-native-images-to-compiled.png

L’outil de moniteur de processus classique peut également être utilisé pour analyser le temps de démarrage de PowerShell. ( https://technet.microsoft.com/en-us/sysinternals/processmonitor.aspx). Exécutez `Procmon64.exe ‘, activez le filtre sur le processus PowerShell.exe, ouvrez le shell PS et identifiez les opérations qui ont provoqué le plus grand retard.

/fr/images/use-process-monitor-to-identify-the-cause-of-the-s.png

Dans mon exemple, la lecture du fichier d’historique des commandes PowerShell maintenue par le module PSREadline a pris environ 30 secondes. (C: \ Users \ Username \ AppData \ Roaming \ Microsoft \ Windows \ PowerShell \ Psreadline \ Consolehost\_history.txt). Le problème a été causé par le fichier Consolehost_history.txt dépassant 2 Go. Le nettoyage du fichier historique a considérablement réduit le temps de démarrage de PowerShell.

  • ️⃣ Lien source:

Logon PowerShell Scripts lancé via GPO, scripts dans les tâches planifiées, History of PowerShell commandes, PowerShell Core, The Intégrin-In Windows Defender Antivirus, https://technet.microsoft.com/en-us/sysinternals/processmonitor.aspx,