Diagnostic et optimisation du CPU de Defender
Quel problème ce skill résout
Sur les machines de développement Windows, la protection en temps réel de Microsoft Defender scanne chaque lecture de fichier. Lorsqu'un processus lit massivement des fichiers (indexation IDEA, analyse de projet par Codex, find / en traversée complète du disque, téléchargement de dépendances Maven, IO interne WSL/Docker), Defender se transforme en pipeline de scan continu, faisant grimper MsMpEng.exe à 50%+ de CPU et ralentissant toute la machine.
L'intuition centrale de ce processus est : un CPU élevé de Defender n'est presque jamais dû à un défaut de Defender lui-même, mais à un processus qui génère des IO massives et déclenche la protection en temps réel. Donc la clé du diagnostic n'est pas de « régler les paramètres de Defender », mais d'identifier la source du déclenchement puis de la retirer du chemin de scan avec une exclusion précise — ce qui résout le ralentissement sans dégrader la posture de sécurité globale.
Processus de diagnostic
Étape 0 : Confirmer que c'est bien Defender, et avec quelle « mesure » de CPU
La colonne CPU du gestionnaire de tâches (Task Manager) et le compteur de performance \Process(*)\% Processor Time ont des échelles différentes : le compteur peut dépasser 100% pour un seul processus sur une machine multi-cœur (chaque cœur ajoute 100%), alors que le gestionnaire de tâches divise cette valeur par le nombre de cœurs. Ainsi, « 61,2% dans le gestionnaire » peut correspondre à 766% sur le compteur (machine à 20 cœurs). Les deux valeurs sont correctes, ne tirez pas de conclusion erronée.
Vérification rapide de l'occupation réelle de MsMpEng (échelle gestionnaire de tâches) :
$cores = $env:NUMBER_OF_PROCESSORS
$c = (Get-Counter '\Process(MsMpEng*)\% Processor Time').CounterSamples | Where-Object { $_.InstanceName -like 'msmpeng*' } | Select-Object -First 1
"MsMpEng : Compteur=$([math]::Round($c.CookedValue,1))% Équivalent gestionnaire=$([math]::Round($c.CookedValue/$cores,1))% (machine $cores cœurs)"
Si le gestionnaire montre une valeur élevée mais que le compteur reste à 0, c'est une valeur obsolète non rafraîchie — il suffit de rouvrir le gestionnaire de tâches, ne modifiez pas Defender.
Étape 1 : Identifier la source déclencheuse (par corrélation, pas par intuition)
Les causes racines d'un CPU élevé de Defender se divisent en trois catégories, avec des méthodes de diagnostic différentes :
| Cause racine | Caractéristique | Comment confirmer |
|---|---|---|
| Protection en temps réel déclenchée par un processus externe (le plus courant) | CPU de MsMpEng fluctuant par impulsions, avec un processus externe générant des IO élevées en même temps | Échantillonnage continu : trouver quel processus a aussi des IO élevées quand MsMpEng monte |
| Analyse planifiée / en arrière-plan | CPU constamment élevé, peu de fluctuations ; ScanRunning a une valeur ou une tâche planifiée est active | Get-MpComputerStatus pour voir ScanRunning ; Get-ScheduledTask -TaskPath '\Microsoft\Windows\Windows Defender\*' |
| Tâches internes de Defender (vérification post-mise à jour des définitions, échantillonnage cloud, etc.) | MsMpEng a le plus d'IO en lecture, mais aucun processus externe avec des IO élevées correspondantes | Échantillonnage : comparer les IO de MsMpEng avec celles des autres processus |
Moyen de diagnostic clé : exécutez scripts/diag-mpcpu.ps1. Il échantillonne pendant plusieurs secondes en enregistrant simultanément le CPU de MsMpEng et les IO Data Bytes/sec de chaque processus. Interprétation :
- Si les IO d'un processus montent en même temps que celles de MsMpEng → ce processus est la source déclencheuse, passez à l'étape 2 pour traiter la cause
- Si MsMpEng a le plus de lectures, sans processus externe à IO élevé → passez à l'étape 3 (tâches internes / analyse)
- Si MsMpEng reste proche de 0 tout du long → le problème n'est plus chez Defender, cherchez ailleurs (l'utilisateur voit peut-être une valeur obsolète du gestionnaire)
Étape 2 : Traiter la cause — ajouter une exclusion pour la source déclencheuse
Il existe deux types d'exclusions, il est important de comprendre la différence :
- Exclusion de processus (ExclusionProcess) : spécifie un nom de processus (ex.
idea64.exe). Ce processus ne déclenche pas de scan lors de ses lectures de fichiers, mais les fichiers restent scannés s'ils sont accédés par d'autres processus. Précis, sécurisé, à privilégier. - Exclusion de chemin (ExclusionPath) : spécifie un répertoire. Les fichiers de ce répertoire ne sont jamais scannés, quel que soit le processus qui les accède (y compris le navigateur, un EDR). Convient pour les caches, disques virtuels qui « ne sont que des fichiers de données, personne ne doit les scanner » ; ne pas l'utiliser pour exclure les répertoires de code source de projets — ceux-ci doivent être protégés par une exclusion de processus (seul l'outil de développement ne déclenche pas de scan, mais un téléchargement par le navigateur dans le même répertoire reste scanné). C'est aussi pourquoi le script
gen-exclusions.ps1ne déduit que des chemins de caches / disques virtuels / répertoires racines d'outils, et n'exclut jamais automatiquement les répertoires de projets.
Pourquoi privilégier l'exclusion de processus : l'exclusion de chemin fait perdre la protection en temps réel à tous les processus pour les fichiers du répertoire ; l'exclusion de processus ne désactive le scan que pour un outil spécifique, ce qui réduit considérablement la surface d'attaque. Par exemple, exclure le processus codex.exe permet à Codex de lire votre projet sans scan, mais un fichier téléchargé par le navigateur dans le même répertoire sera toujours scanné — c'est exactement ce que nous voulons.
Exécutez scripts/gen-exclusions.ps1 — il parcourt les processus de développement en cours, les fait correspondre à des modèles d'outils connus et génère automatiquement des exclusions recommandées (processus + chemins). Par défaut en mode DryRun (affiche les suggestions avec justifications). Confirmez puis exécutez avec -Apply pour les appliquer à Defender. Il est idempotent et sauvegarde les exclusions actuelles avant toute modification.
Étape 3 : Traitement des causes racines liées aux analyses en arrière-plan
S'il s'agit d'une analyse planifiée / d'une maintenance automatique en cours (ScanRunning a une valeur, tâche planifiée à l'état Running), il faut généralement la laisser se terminer — ne l'interrompez pas brutalement : c'est une maintenance de sécurité nécessaire effectuée par Defender. Si elle se déclenche répétitivement à des moments inopportuns, ajustez la planification :
# Voir les analyses planifiées
Get-ScheduledTask -TaskPath '\Microsoft\Windows\Windows Defender\*'
# Ajuster l'heure de l'analyse rapide (ex. tous les jours à 3h du matin) — attention, cela écrase la configuration existante
Set-MpPreference -ScanScheduleQuickScanTime 03:00:00
S'il s'agit d'une vérification complète après une mise à jour des définitions (occasionnelle), elle se termine généralement en une fois, laissez-la faire.
Étape 4 : Validation
Après avoir ajouté les exclusions, déclenchez à nouveau la charge IO d'origine (rouvrez l'IDE, relancez find, laissez Codex analyser le projet), puis relancez diag-mpcpu.ps1. Le critère de succès est : avec la même charge IO, MsMpEng passe de sa valeur élevée initiale à proche de 0. Si ce n'est pas le cas, les exclusions ne couvrent pas la véritable source déclencheuse — retournez à l'étape 1 et examinez la sortie de diag pour trouver quel processus continue de monter en même temps.
Limites de sécurité — ces éléments ne doivent jamais être exclus
Les exclusions réduisent la protection en temps réel pour le chemin/processus concerné, donc des limites sont nécessaires. Les éléments suivants ne doivent jamais être exclus, quelle que soit leur consommation CPU apparente (la liste complète et faisant foi est dans $denyProcs et $denyPathPrefix du script scripts/gen-exclusions.ps1 ; cette liste documentaire est uniquement indicative) :
- Processus système :
svchost.exe,dllhost.exe,smartscreen.exe,conhost.exe,lsass.exe,csrss.exe, etc. - Navigateurs et leurs WebView :
msedge.exe,chrome.exe,msedgewebview2.exe— les téléchargements par navigateur sont la principale porte d'entrée des malwares, gardez le scan - Clients de sécurité / de contrôle : les EDR, VPN clients installés par l'entreprise (ex. 深信服 ECAgent, CrowdStrike, SentinelOne) — les modifier pourrait déclencher des alertes de conformité, et ils font partie de la ligne de défense
- Le répertoire utilisateur entier ou la racine du disque système : trop large, équivaut à être complètement exposé
- Extensions de fichiers exécutables (
*.jar,*.exe,*.dll,*.ps1, etc.) : ce sont des exécutables, gardez le scan. Les extensions exclues ne devraient concerner que des artefacts de compilation purs (.class) ou des fichiers journaux (.log), qui ne sont pas exécutables
Principe de décision : Les exclusions doivent cibler « les fichiers lus par un outil de développement de confiance dans le cadre de son travail normal », pas « exclure tout pour économiser du CPU ».
Diagnostic avancé : Enregistreur de performance
Lorsque le script de diagnostic n'identifie toujours pas précisément la source, utilisez l'enregistreur de performance officiel de Defender (nécessite des droits administrateur) — il fournit un rapport précis sur les chemins/processus où MsMpEng passe le plus de temps :
New-MpPerformanceRecord -RecordTo C:\perf.mpdr # Collecte pendant 60s (reproduisez le pic CPU)
# Le rapport indique les chemins et processus les plus consommateurs en CPU, pour ajouter des exclusions ciblées
Fichiers de référence
references/common-exclusions.md— Liste catégorisée des exclusions recommandées pour les outils de développement courants (IDE/Java/Node/WSL/Docker/assistants de codage IA/caches de build), avec explications du compromis sécurité pour chaque catégorie. Utilisez-la pour vérifier la couverture des exclusions générées.scripts/diag-mpcpu.ps1— Script d'échantillonnage de diagnosticscripts/gen-exclusions.ps1— Script pour générer et appliquer automatiquement les exclusions (aperçu par défaut)