Les problèmes de performance ne se présentent pas poliment. Ils se manifestent par « l’application est lente », « le RDP est saccadé », « le SQL est bloqué », ou ma préférée : « hier tout allait bien ». Au moment où vous ouvrez le Gestionnaire des tâches, le pic a déjà quitté la scène du crime.
Get-Counter de PowerShell est votre caméra de surveillance : toujours allumée, horodatée, automatisable et recevable comme preuve. Si vous apprenez à lire une poignée de compteurs comme un SRE lit des graphiques, vous pouvez distinguer la famine CPU de la pression mémoire ou de la latence disque en quelques minutes — et pas des heures de diagnostic basé sur des impressions.
Pourquoi Get‑Counter vaut mieux que de cliquer partout
PerfMon est suffisant. Le Gestionnaire des tâches est suffisant. Mais « suffisant » n’est pas ce qu’il vous faut à 02:13 quand un serveur de fichiers commence à répondre au ralenti et que vous avez 15 minutes avant qu’un VP trouve votre numéro.
Get-Counter gagne parce qu’il est :
- Scriptable : intervalles d’échantillonnage répétables, sortie cohérente, exportations faciles.
- Convient pour le distant : la même commande peut s’exécuter contre plusieurs hôtes.
- Orienté séries temporelles : vous pouvez capturer un pic, pas seulement regarder un instantané.
- Composable : pipez-le, filtrez-le, agrégez-le, planifiez-le.
Et vous n’avez plus à « vous souvenir de ce que vous avez cliqué » pendant un incident. La commande elle‑même fait office d’enregistrement.
Une règle pratique : arrêtez de demander « le CPU est-il élevé ? » et commencez à demander « quelle ressource est le réactif limitant en ce moment ? » CPU, mémoire et disque forment un combat à trois. Votre rôle est d’identifier qui tient le couteau.
Blague #1 : Si vous ne basez pas vos compteurs, chaque graphique devient une « détection d’anomalie » alimentée par la panique et le café.
Faits intéressants et histoire (qui a vraiment de l’intérêt)
- Les compteurs de performance Windows précèdent PowerShell. Ils existent depuis l’ère NT ; PowerShell est ensuite devenu un moyen pratique de les interroger sans l’interface graphique.
- PerfMon n’est qu’un client. Les données des compteurs proviennent de fournisseurs (comme
PerfProc,PerfOS) et d’instrumentations dans l’OS et les pilotes. - Les instances peuvent disparaître. Les compteurs de processus utilisent des instances comme
chrome#3; quand les processus redémarrent, les noms d’instance peuvent changer, rompant les automatisations naïves. - Certains compteurs « classiques » trompent par omission. La longueur de la file d’attente disque peut être trompeuse sur des piles de stockage modernes avec cache et parallélisme ; la latence est souvent la vérité la plus fiable.
- Les hyperviseurs ont changé la signification du « % CPU ». Le temps ready, le temps volé et la planification côté hôte peuvent provoquer des ralentissements même si le CPU invité semble modéré.
- Le type de compteur compte. Certaines valeurs sont des débits (par seconde), d’autres sont des comptes bruts, d’autres des fractions ;
CookedValueest PowerShell qui fait le calcul pour vous. - L’intervalle d’échantillonnage change l’interprétation. Un échantillon à 1 seconde capture les pics ; un échantillon à 30 secondes les masque. Ce n’est pas de la philosophie — c’est des maths.
- Beaucoup de compteurs sont calculés, pas mesurés. Par exemple, « % Processor Time » est dérivé des deltas du temps d’inactivité, pas d’un compteur magique du CPU.
- Les requêtes à distance utilisent RPC/Perf. Elles peuvent être bloquées par des règles de pare-feu, durcissements de service ou permissions, même si WinRM fonctionne.
Un modèle mental utile : CPU vs RAM vs Disque
Goulots CPU : problèmes rapides, symptômes évidents, « correctifs » trompeurs
Les problèmes CPU se manifestent souvent par un % Processor Time élevé, de longues files d’attente d’exécution et une réponse lente partout. Mais le CPU est aussi où les gens se piègent : ils voient 80–90% CPU et demandent immédiatement plus de cœurs. Parfois c’est la bonne solution. Souvent c’est un pansement sur du mauvais code, un scan antivirus agressif, un formateur de logs incontrôlé ou une boucle d’attente active qui aurait dû dormir.
Le CPU est aussi l’endroit où la virtualisation cache les péchés. Une VM invitée peut sembler « correcte » alors que l’hôte est surabonné et que votre VM attend d’être planifiée. Si vous ne mesurez que depuis l’invité, vous pouvez manquer le vrai problème.
Goulots mémoire : le désastre au ralenti
La pression mémoire ruine votre journée lentement, puis soudainement. Windows va tout faire pour maintenir le fonctionnement en réduisant les working sets et en paginant. Au moment où les utilisateurs se plaignent, vous êtes souvent déjà sur le « tapis roulant de pagination » : le disque commence à thrash, le CPU grimpe, et tout devient incohérent. C’est pourquoi le diagnostic mémoire doit inclure à la fois la mémoire disponible et l’activité de pagination.
Goulots disque : la latence est la métrique reine
Les problèmes disque concernent rarement des plafonds de débit ; ils concernent la latence et la latence de queue (tail latency). Un système de stockage peut atteindre des MB/s impressionnants et quand même ruiner votre application si les lectures prennent 50–200 ms lors des rafales. Pour la plupart des charges Windows, si vous pouvez répondre à « quelle est la latence de lecture/écriture maintenant ? », vous êtes à mi-chemin de la solution.
Et oui, « disque » peut signifier un SAN, un volume cloud, Storage Spaces, un cache de contrôleur RAID, un pilote filtre antivirus, ou une tempête de métadonnées du système de fichiers. Les compteurs ne nomment pas automatiquement le coupable, mais ils vous diront s’il faut d’abord chasser l’I/O, le CPU ou la mémoire.
Une citation qui devrait figurer dans chaque runbook d’astreinte, parce qu’elle vous remettra à votre place :
« L’espoir n’est pas une stratégie. » — General Gordon R. Sullivan
Utilisez des compteurs. Pas l’espoir.
Tâches pratiques (commandes + sorties + décisions)
Ci‑dessous, des tâches réelles à exécuter pendant les incidents ou pour établir des baselines. Chacune comprend : la commande, ce que la sortie signifie, et la décision à en tirer.
Tâche 1 : Lister les compteurs disponibles pour CPU, mémoire, disque
cr0x@server:~$ powershell -NoProfile -Command "Get-Counter -ListSet Processor,Memory,PhysicalDisk | Select-Object -ExpandProperty Counter"
\\Processor(*)\\% Processor Time
\\Processor(*)\\% Privileged Time
\\Processor(*)\\% User Time
\\Processor(*)\\Interrupts/sec
\\Processor(*)\\% Idle Time
\\Memory\\Available MBytes
\\Memory\\Committed Bytes
\\Memory\\% Committed Bytes In Use
\\Memory\\Cache Faults/sec
\\Memory\\Pages/sec
\\PhysicalDisk(*)\\Avg. Disk sec/Read
\\PhysicalDisk(*)\\Avg. Disk sec/Write
\\PhysicalDisk(*)\\Disk Reads/sec
\\PhysicalDisk(*)\\Disk Writes/sec
\\PhysicalDisk(*)\\Current Disk Queue Length
Ce que ça signifie : Votre système expose ces compteurs ; les noms varient selon la version OS et les rôles installés. Vous ne pouvez pas interroger ce qui n’existe pas.
Décision : Choisissez les compteurs selon la question à laquelle vous répondez (latence, débit, saturation), pas selon ce qui vous semble familier.
Tâche 2 : Instantané CPU rapide (global)
cr0x@server:~$ powershell -NoProfile -Command "Get-Counter '\Processor(_Total)\% Processor Time' | Select-Object -ExpandProperty CounterSamples | Select-Object Path,CookedValue"
Path CookedValue
---- -----------
\\server\\processor(_total)\\% processor time 37.248
Ce que ça signifie : CookedValue est un pourcentage. Un échantillon unique est un indice, pas un verdict.
Décision : S’il est élevé, n’agissez pas encore. Prenez une courte série temporelle ensuite.
Tâche 3 : Série temporelle CPU (attraper les pics)
cr0x@server:~$ powershell -NoProfile -Command "Get-Counter '\Processor(_Total)\% Processor Time' -SampleInterval 1 -MaxSamples 10 | Select-Object -ExpandProperty CounterSamples | Select-Object TimeStamp,CookedValue"
TimeStamp CookedValue
--------- -----------
2/5/2026 2:13:01 AM 41.1
2/5/2026 2:13:02 AM 92.3
2/5/2026 2:13:03 AM 88.7
2/5/2026 2:13:04 AM 54.9
2/5/2026 2:13:05 AM 39.2
2/5/2026 2:13:06 AM 36.8
2/5/2026 2:13:07 AM 35.5
2/5/2026 2:13:08 AM 34.9
2/5/2026 2:13:09 AM 35.2
2/5/2026 2:13:10 AM 36.1
Ce que ça signifie : Vous avez eu un vrai pic (90%+) pendant quelques secondes. Cela peut être normal (GC, compactage, tâches planifiées) ou pathologique.
Décision : Si les pics coïncident avec la douleur utilisateur, vérifiez ensuite si le CPU effectue du travail utilisateur ou noyau.
Tâche 4 : Temps CPU utilisateur vs privilégié (pression noyau)
cr0x@server:~$ powershell -NoProfile -Command "Get-Counter '\Processor(_Total)\% User Time','\Processor(_Total)\% Privileged Time' -SampleInterval 1 -MaxSamples 5 | Select-Object -ExpandProperty CounterSamples | Select-Object Path,CookedValue"
Path CookedValue
---- -----------
\\server\\processor(_total)\\% user time 22.4
\\server\\processor(_total)\\% privileged time 18.7
\\server\\processor(_total)\\% user time 23.1
\\server\\processor(_total)\\% privileged time 41.2
\\server\\processor(_total)\\% user time 21.9
\\server\\processor(_total)\\% privileged time 39.5
Ce que ça signifie : Une montée du temps privilégié suggère du travail noyau : pilotes, pile de stockage, pilotes filtre antivirus, réseau intensif, changements de contexte ou tempêtes d’interruptions.
Décision : Si le temps privilégié est élevé, regardez la latence disque et les interruptions avant d’accuser « l’application ».
Tâche 5 : Longueur de file d’attente processeur (des threads attendent‑ils ?)
cr0x@server:~$ powershell -NoProfile -Command "Get-Counter '\System\Processor Queue Length' -SampleInterval 1 -MaxSamples 10 | Select-Object -ExpandProperty CounterSamples | Select-Object TimeStamp,CookedValue"
TimeStamp CookedValue
--------- -----------
2/5/2026 2:14:01 AM 0
2/5/2026 2:14:02 AM 2
2/5/2026 2:14:03 AM 8
2/5/2026 2:14:04 AM 9
2/5/2026 2:14:05 AM 7
2/5/2026 2:14:06 AM 1
2/5/2026 2:14:07 AM 0
2/5/2026 2:14:08 AM 0
2/5/2026 2:14:09 AM 1
2/5/2026 2:14:10 AM 0
Ce que ça signifie : Ce sont des threads exécutables en attente de CPU. Sur un système multi‑cœurs, interprétez‑le par rapport au nombre de cœurs. Les pics peuvent être normaux ; une file soutenue suggère une contention CPU.
Décision : Si la longueur de file reste au‑dessus de quelques éléments par cœur sur des intervalles soutenus, réduisez la demande CPU ou ajoutez de la capacité. Si elle pique brièvement, cherchez la source du pic.
Tâche 6 : Disponibilité mémoire (le contrôle le plus simple « sommes‑nous à l’étroit ? »)
cr0x@server:~$ powershell -NoProfile -Command "Get-Counter '\Memory\Available MBytes' -SampleInterval 2 -MaxSamples 5 | Select-Object -ExpandProperty CounterSamples | Select-Object TimeStamp,CookedValue"
TimeStamp CookedValue
--------- -----------
2/5/2026 2:15:01 AM 612
2/5/2026 2:15:03 AM 590
2/5/2026 2:15:05 AM 571
2/5/2026 2:15:07 AM 548
2/5/2026 2:15:09 AM 530
Ce que ça signifie : La mémoire disponible est en baisse. Le seuil « mauvais » absolu dépend du rôle. Les contrôleurs de domaine et serveurs de fichiers tolèrent moins de mémoire libre que les bases de données gourmandes en mémoire.
Décision : Si elle est faible et en baisse, vérifiez les octets engagés et l’activité de pagination avant de déclarer « besoin de plus de RAM ».
Tâche 7 : Pression de commit (approchons‑nous de la limite de commit ?)
cr0x@server:~$ powershell -NoProfile -Command "Get-Counter '\Memory\% Committed Bytes In Use','\Memory\Committed Bytes' | Select-Object -ExpandProperty CounterSamples | Select-Object Path,CookedValue"
Path CookedValue
---- -----------
\\server\\memory\\% committed bytes in use 91.6
\\server\\memory\\committed bytes 2.941943e+10
Ce que ça signifie : Un commit proche de 90% est un signal d’alarme. Le commit est la mémoire virtuelle qui doit être supportée par la RAM ou les fichiers d’échange. Si le commit atteint 100%, les allocations échouent et les services tombent de façons créatives.
Décision : À un usage soutenu de 85–95%+, réduisez l’utilisation mémoire, corrigez les fuites ou augmentez RAM/pagefile. N’attendez pas 100%.
Tâche 8 : Taux de pagination (le système thrash‑il ?)
cr0x@server:~$ powershell -NoProfile -Command "Get-Counter '\Memory\Pages/sec' -SampleInterval 1 -MaxSamples 10 | Select-Object -ExpandProperty CounterSamples | Select-Object TimeStamp,CookedValue"
TimeStamp CookedValue
--------- -----------
2/5/2026 2:16:01 AM 12
2/5/2026 2:16:02 AM 18
2/5/2026 2:16:03 AM 220
2/5/2026 2:16:04 AM 410
2/5/2026 2:16:05 AM 395
2/5/2026 2:16:06 AM 205
2/5/2026 2:16:07 AM 44
2/5/2026 2:16:08 AM 16
2/5/2026 2:16:09 AM 14
2/5/2026 2:16:10 AM 13
Ce que ça signifie : Une rafale de pagination peut être normale. Une pagination soutenue avec faible mémoire disponible et latence disque croissante est la signature classique de pression mémoire.
Décision : Si la pagination est soutenue et que la latence disque augmente, traitez la mémoire comme le goulot principal même si « le disque semble occupé ». Le disque est la victime ici.
Tâche 9 : Latence disque par volume (la métrique clé)
cr0x@server:~$ powershell -NoProfile -Command "Get-Counter '\PhysicalDisk(*)\Avg. Disk sec/Read','\PhysicalDisk(*)\Avg. Disk sec/Write' | Select-Object -ExpandProperty CounterSamples | Sort-Object CookedValue -Descending | Select-Object -First 8 Path,CookedValue"
Path CookedValue
---- -----------
\\server\\physicaldisk(1 d:)\\avg. disk sec/write 0.187
\\server\\physicaldisk(1 d:)\\avg. disk sec/read 0.142
\\server\\physicaldisk(0 c:)\\avg. disk sec/write 0.021
\\server\\physicaldisk(0 c:)\\avg. disk sec/read 0.009
Ce que ça signifie : La latence est en secondes. 0,187 s correspond à 187 ms de latence en écriture, ce qui est mauvais pour la plupart des charges transactionnelles. Des lectures à 142 ms ne sont pas non plus acceptables.
Décision : Si un volume spécifique montre une latence élevée, concentrez l’investigation là‑dessus : quel workload l’atteint, qu’est‑ce qui a changé, et s’il s’agit de capacité, de chemin ou de saturation du backend.
Tâche 10 : Longueur de file disque (contexte, pas verdict)
cr0x@server:~$ powershell -NoProfile -Command "Get-Counter '\PhysicalDisk(*)\Current Disk Queue Length' | Select-Object -ExpandProperty CounterSamples | Sort-Object CookedValue -Descending | Select-Object -First 6 Path,CookedValue"
Path CookedValue
---- -----------
\\server\\physicaldisk(1 d:)\\current disk queue length 23
\\server\\physicaldisk(0 c:)\\current disk queue length 1
Ce que ça signifie : Requêtes en attente sur le disque. Une file de 23 peut être acceptable sur un stockage très parallèle — ou catastrophique sur un disque SATA unique. Sans la latence, la file n’est qu’une moitié d’histoire.
Décision : Utilisez la longueur de file pour soutenir la conclusion sur la latence, pas pour la remplacer.
Tâche 11 : Débit disque (saturons‑nous la bande passante ?)
cr0x@server:~$ powershell -NoProfile -Command "Get-Counter '\PhysicalDisk(*)\Disk Read Bytes/sec','\PhysicalDisk(*)\Disk Write Bytes/sec' | Select-Object -ExpandProperty CounterSamples | Sort-Object CookedValue -Descending | Select-Object -First 10 Path,CookedValue"
Path CookedValue
---- -----------
\\server\\physicaldisk(1 d:)\\disk write bytes/sec 8.941122e+07
\\server\\physicaldisk(1 d:)\\disk read bytes/sec 2.110294e+07
\\server\\physicaldisk(0 c:)\\disk write bytes/sec 1.240122e+06
\\server\\physicaldisk(0 c:)\\disk read bytes/sec 3.901220e+06
Ce que ça signifie : Bytes/sec. Sur D: vous effectuez ~89 MB/s en écritures et ~21 MB/s en lectures. Cela peut être normal pour une tâche de sauvegarde, terrible pour une base de données sensible à la latence, ou les deux.
Décision : Si le débit est élevé et la latence aussi, vous saturez quelque chose. Si le débit est faible mais la latence élevée, vous avez de la contention, des problèmes de backend ou un motif d’I/O pathologique.
Tâche 12 : Identifier le processus consommant le CPU (top offenders)
cr0x@server:~$ powershell -NoProfile -Command "Get-Process | Sort-Object CPU -Descending | Select-Object -First 8 Name,Id,CPU,WorkingSet64"
Name Id CPU WorkingSet64
---- -- --- ------------
w3wp 4120 812.3 1245184000
MsMpEng 2788 410.7 512245760
sqlservr 1556 209.1 8421191680
svchost 1020 88.5 210796544
Ce que ça signifie : Il s’agit du temps CPU cumulatif depuis le démarrage du processus, pas de l’instantané CPU%. Toujours utile : si quelque chose a un temps CPU absurde sur une courte durée d’activité, c’est un candidat.
Décision : Si le CPU est élevé maintenant, corrélez‑le avec les compteurs de séries temporelles ; si le principal responsable est un scan de sécurité, replanifiez ou ajustez les exclusions (avec gouvernance).
Tâche 13 : Vérification CPU distante sur plusieurs serveurs
cr0x@server:~$ powershell -NoProfile -Command "$servers='app01','app02','db01'; Get-Counter '\Processor(_Total)\% Processor Time' -ComputerName $servers | Select-Object -ExpandProperty CounterSamples | Select-Object PSComputerName,TimeStamp,CookedValue"
PSComputerName TimeStamp CookedValue
-------------- --------- -----------
app01 2/5/2026 2:17:01 AM 18.2
app02 2/5/2026 2:17:01 AM 22.7
db01 2/5/2026 2:17:01 AM 79.4
Ce que ça signifie : Vous venez d’établir le rayon d’impact : la DB est chaude, les apps ne le sont pas. C’est ainsi que vous évitez le debug au hasard.
Décision : Concentrez‑vous sur db01 ensuite : latence disque, comportement du cache, pagination et pression de requêtes.
Tâche 14 : Exporter une courte capture en CSV pour preuve
cr0x@server:~$ powershell -NoProfile -Command "$c='\Processor(_Total)\% Processor Time','\Memory\Available MBytes','\Memory\Pages/sec','\PhysicalDisk(_Total)\Avg. Disk sec/Read','\PhysicalDisk(_Total)\Avg. Disk sec/Write'; Get-Counter $c -SampleInterval 2 -MaxSamples 30 | Export-Counter -Path C:\temp\triage.blg"
Ce que ça signifie : Vous avez capturé une fenêtre de 60 secondes dans un fichier BLG. C’est natif PerfMon et peut être ouvert ou analysé plus tard.
Décision : Lors d’incidents, capturez toujours des preuves avant de redémarrer des choses. « On a redémarré et c’est revenu » n’est pas une cause racine.
Tâche 15 : Parser un BLG et convertir en CSV (partageable)
cr0x@server:~$ powershell -NoProfile -Command "Import-Counter C:\temp\triage.blg | Export-Counter -FileFormat CSV -Path C:\temp\triage.csv"
Ce que ça signifie : Vous avez maintenant un CSV que vous pouvez ouvrir dans Excel, ingérer dans une base temporelle ou comparer avec une baseline.
Décision : Utilisez le CSV pour montrer les tendances (latence qui monte avec la pagination, CPU qui pique avec le temps noyau) et éviter les débats basés sur des impressions.
Tâche 16 : Surveiller une instance de volume spécifique de façon fiable (éviter de prendre la mauvaise instance)
cr0x@server:~$ powershell -NoProfile -Command "Get-Counter -ListSet PhysicalDisk | Select-Object -ExpandProperty PathsWithInstances | Where-Object { $_ -like '*Avg. Disk sec/Read*' } | Select-Object -First 8"
\\PhysicalDisk(0 C:)\\Avg. Disk sec/Read
\\PhysicalDisk(1 D:)\\Avg. Disk sec/Read
\\PhysicalDisk(_Total)\\Avg. Disk sec/Read
\\PhysicalDisk(2 E:)\\Avg. Disk sec/Read
Ce que ça signifie : Vous énumérez les chemins d’instance exacts. Cela vous évite d’échantillonner une instance qui n’existe pas sur un autre serveur (ou dont le nom a changé).
Décision : Découvrez toujours les chemins d’instance de façon programmatique lorsque vous écrivez des scripts destinés à s’exécuter sur une flotte.
Playbook de diagnostic rapide
Ceci est la séquence « j’ai cinq minutes ». Vous ne prouvez pas une thèse. Vous trouvez le goulot assez vite pour arrêter l’hémorragie.
Première étape : établir le périmètre du symptôme
- Hôte unique ou plusieurs ? Échantillonnez rapidement le CPU sur les serveurs suspectés (Tâche 13). Si une seule machine est chaude, n’allez pas creuser partout.
- Volume unique ou plusieurs ? Vérifiez la latence disque par volume (Tâche 9). Si seul D: souffre, ne touchez pas C:.
Deuxième étape : identifier la ressource limitante
- Saturation CPU ? Regardez
\Processor(_Total)\% Processor Timeet\System\Processor Queue Length(Tâches 3 et 5). Un CPU élevé sans file peut encore être « occupé mais gère ». Une file élevée signifie que des threads attendent. - Pression mémoire ? Vérifiez
\Memory\Available MBytes,\Memory\% Committed Bytes In Use, et\Memory\Pages/sec(Tâches 6–8). Mémoire disponible faible + commit élevé + pagination soutenue est la signature. - Latence disque ? Vérifiez
\PhysicalDisk(*)\Avg. Disk sec/ReadetWrite(Tâche 9). Si la latence est élevée, tout le reste semblera mauvais.
Troisième étape : décider d’atténuer ou d’investiguer
- Si le CPU est le goulot : trouvez les processus principaux, vérifiez le temps privilégié (Tâches 4 et 12). Atténuez par throttling, replanification des jobs batch ou mise à l’échelle temporaire. Ne redémarrez pas les services aveuglément sauf en cas de fuite ou de thread en runaway.
- Si la mémoire est le goulot : stoppez la croissance (processus fuyant, cache incontrôlé, service mal configuré). Atténuez en réduisant la charge, en redémarrant le coupable si nécessaire, et en dimensionnant correctement le pagefile. Si vous paginez fort, le disque semblera coupable — ignorez le leurre.
- Si la latence disque est le goulot : identifiez le volume et le workload. Atténuez en mettant en pause les jobs lourds, en déplaçant les chemins temporaires, en vérifiant la santé du backend ou en basculant si l’architecture le permet. Ajouter du CPU pour résoudre une latence stockage, c’est crier sur une barre de chargement.
Trois mini‑histoires d’entreprise issues du terrain
Mini‑histoire #1 : L’incident provoqué par une fausse hypothèse
Une entreprise de taille moyenne avait un serveur de fichiers Windows critique qui « gelait aléatoirement » tous les matins en semaine. L’hypothèse du premier intervenant était simple : « Le CPU grimpe à 9h, donc c’est le CPU. » Ils ont demandé une VM plus grosse et plus de vCPU. La demande a été approuvée parce que cela paraissait raisonnable, et tout le monde aime une histoire d’approvisionnement propre.
Après le changement, le gel est revenu. Le CPU semblait plus bas, mais l’expérience utilisateur ne s’était pas améliorée. Cela aurait dû être l’indice : baisser l’utilisation CPU sans améliorer la latence signifie que le CPU n’était pas le limiteur.
Le deuxième intervenant a fait quelque chose d’ennuyeux : il a capturé une trace de compteurs d’une minute pendant l’événement. \PhysicalDisk(…)\Avg. Disk sec/Write est passé de quelques millisecondes à des centaines de millisecondes. En même temps, \Memory\Pages/sec était élevé et \Processor(_Total)\% Privileged Time a grimpé. Le sous‑système de stockage éprouvait des timeouts sous une charge d’écriture intensive.
Le coupable n’était pas « le disque est lent » en abstracto. C’était un job planifié qui déposait des millions de petits fichiers dans un seul répertoire sur un volume hébergé sur un stockage partagé, exactement au moment où les snapshots VSS s’exécutaient. Churn de métadonnées + IO de snapshot + contention backend : une tempête parfaite de comportements Windows ennuyeux.
La correction n’a pas été plus de CPU. C’était replanifier le job, répartir la sortie sur plusieurs répertoires, ajuster le timing des snapshots et ajouter un volume séparé pour cette charge. L’argent économisé en n’achetant pas de vCPU a ensuite servi à améliorer le stockage.
Mini‑histoire #2 : L’optimisation qui s’est retournée contre eux
Une équipe applicative voulait des déploiements plus rapides. Ils ont paramétré un service Windows pour cacher plus de données en mémoire, afin de réduire les appels DB. Ça a fonctionné en staging. En production aussi — jusqu’à ce que le trafic augmente et que le cache dépasse sa « cible douce ».
L’utilisation mémoire a monté lentement. Personne ne l’a remarqué car les serveurs avaient « beaucoup de RAM » et Windows ne criait pas fort. Mais \Memory\% Committed Bytes In Use augmentait. Puis la pagination a commencé. La latence disque est montée. Le temps privilégié CPU a augmenté. Le système est entré dans le tapis roulant de pagination : tout était techniquement « up », mais les temps de réponse étaient terribles.
La première tentative de correction a été de déplacer le pagefile vers un volume plus rapide. Ça a aidé un peu, juste assez pour masquer le problème et prolonger l’incident. C’est le piège : optimiser la pagination, c’est comme mettre de plus belles rampes d’escalier dans un sous‑sol où il ne faut pas vivre.
La bonne correction a été de plafonner le cache, d’ajouter une éviction et de séparer les objets « chauds » des « agréables à avoir ». Ils ont aussi ajouté une alerte basée sur compteurs : si l’usage de commit restait élevé et que la pagination dépassait un seuil pendant plusieurs minutes, l’équipe était réveillée avant les utilisateurs.
La leçon : certaines « optimisations » de performance sont en réalité des stratégies de consommation de ressources. Si vous ne mesurez pas le commit et la pagination, vous pouvez livrer une bombe à retardement sous forme d’un feature flag.
Mini‑histoire #3 : La pratique ennuyeuse mais correcte qui a sauvé la mise
Un environnement finance exécutait des jobs batch la nuit : imports, génération de rapports et ETL sur des serveurs Windows connectés à un stockage partagé. Les jobs étaient prévisibles, mais l’environnement avait une chose que beaucoup n’ont pas : des baselines. Chaque semaine, une tâche planifiée capturait une courte trace de compteurs pendant les fenêtres de batch de pointe et l’archivait.
Une nuit, les rapports ont commencé à rater leurs délais. L’équipe opérations n’a pas perdu de temps à se demander qui avait changé quoi. Ils ont tiré les captures hebdomadaires et comparé la latence et le débit disque. La latence a bondi sur un volume unique tandis que le débit restait stable. Ce motif criait « contention backend ou problème de chemin de stockage », pas « workload augmenté ».
Ils ont ensuite vérifié quelques autres serveurs. Même volume, même fenêtre horaire, même signature de latence. Cela a établi que ce n’était pas un voisin bruyant dans une VM. C’était systémique.
Les ingénieurs stockage ont trouvé un basculement de chemin sur le côté SAN qui ne s’était pas pleinement reconstruit vers des chemins optimaux, laissant le trafic sur une route sous‑optimale. Réparer le chemin a rétabli la latence immédiatement, et les jobs batch ont fini dans leur fenêtre normale.
Ce n’était pas de l’héroïsme. C’était une collecte de preuves routinière. La discipline ennuyeuse — captures de baseline — a transformé une possible guerre de nuit en une correction en 30 minutes.
Blague #2 : Le système de surveillance le plus fiable est celui que vous avez configuré avant que votre patron n’apprenne le mot « latence ».
Erreurs courantes (symptôme → cause racine → correctif)
1) « Le CPU n’est qu’à 40% mais le serveur est lent »
Symptôme : Les utilisateurs subissent des timeouts ; le CPU semble modéré.
Cause racine : Latence disque ou pression mémoire provoquant des threads bloqués en I/O ; le CPU paraît « libre » parce que des threads attendent.
Correctif : Vérifiez \PhysicalDisk(*)\Avg. Disk sec/Read/Write et \Memory\Pages/sec. Si la latence est élevée, corrigez le chemin I/O ou le workload. Si la pagination est élevée, traitez la pression mémoire.
2) « La longueur de file disque est élevée, donc le stockage est en cause »
Symptôme : Pics de longueur de file ; quelqu’un ping l’équipe stockage.
Cause racine : La longueur de file dépend du contexte ; elle augmente sous I/O parallèle normal et en cache. Elle peut aussi augmenter lors d’une pagination mémoire.
Correctif : Utilisez la latence comme indicateur principal. Une longueur de file sans latence élevée n’est pas un incident. Longueur de file avec latence élevée est actionnable.
3) « On a résolu en ajoutant des vCPU »
Symptôme : Le % CPU a baissé après l’ajout de cœurs ; les utilisateurs se plaignent toujours.
Cause racine : Le CPU n’était pas le goulot ; vous avez juste changé le dénominateur. Ou vous avez introduit des problèmes de planification/NUMA.
Correctif : Validez avec \System\Processor Queue Length et les compteurs disque/mémoire. Si la file n’était pas élevée avant, le CPU n’était pas le limiteur. Revenez en arrière si cela complique le placement NUMA.
4) « Available MBytes est bas, on est à court de mémoire »
Symptôme : Faible mémoire disponible ; des alarmes se déclenchent ; on commande de la RAM.
Cause racine : Windows utilise la mémoire agressivement pour le cache ; une faible mémoire disponible seule n’est pas une preuve de pression.
Correctif : Confirmez avec % Committed Bytes In Use et Pages/sec. Faible disponible + commit élevé + pagination soutenue = pression. Faible disponible + faible pagination peut être acceptable.
5) « La pagination est non nulle, donc c’est mauvais »
Symptôme : Pages/sec montre de l’activité ; panique générale.
Cause racine : Des rafales de pagination arrivent ; l’OS taille et gère les working sets. Une valeur non nulle est normale ; soutenue et élevée, elle ne l’est pas.
Correctif : Faites un trend. Prenez 60–120 secondes d’échantillons et corrélez avec la latence et la douleur utilisateur.
6) « La sortie Get-Counter est étrange ; les nombres sont en notation scientifique »
Symptôme : Des valeurs comme 2.94e+10 apparaissent.
Cause racine : PowerShell formate les grands nombres en notation scientifique.
Correctif : Formatez explicitement la sortie (par ex., arrondir/convertir les unités) lorsque vous la rapportez à des humains. Ne changez pas la collecte ; changez la présentation.
7) « Les compteurs diffèrent entre serveurs, le script est cassé »
Symptôme : Les requêtes distantes échouent ou retournent des instances manquantes.
Cause racine : Le nommage des instances diffère (disques, NIC, processus) ; rôles/fonctionnalités changent les ensembles de compteurs disponibles.
Correctif : Découvrez PathsWithInstances par hôte avant d’échantillonner. Évitez de coder en dur les noms d’instance quand vous pouvez interroger par motif.
8) « Nous avons échantillonné toutes les 60 secondes et n’avons rien vu »
Symptôme : Les utilisateurs se plaignent de pics ; les compteurs semblent calmes.
Cause racine : Vous avez choisi un intervalle d’échantillonnage qui moyenne le problème.
Correctif : Utilisez 1–2 secondes d’échantillonnage pendant le triage, puis élargissez après avoir capté la signature.
Listes de contrôle / plan étape par étape
Checklist A : Construire une baseline (faites‑le une fois, remerciez‑vous plus tard)
- Choisissez 10–15 compteurs pour votre rôle (web/app/DB/serveur de fichiers). Ensemble minimum :
\Processor(_Total)\% Processor Time\System\Processor Queue Length\Memory\Available MBytes\Memory\% Committed Bytes In Use\Memory\Pages/sec\PhysicalDisk(*)\Avg. Disk sec/Read\PhysicalDisk(*)\Avg. Disk sec/Write
- Capturez pendant 5–15 minutes lors des périodes « normales de charge », pas à 3h du matin quand rien ne se passe.
- Stockez les fichiers BLG dans un emplacement prévisible avec des timestamps.
- Documentez ce que « normal » signifie : plages de latence typiques, pics CPU habituels, et quels jobs tournent quand.
Checklist B : Capture en incident (kit de preuves minimum)
- Démarrez une capture de 60–120 secondes à intervalles de 1–2 secondes pour CPU/mémoire/latence disque (Tâche 14, ajustez les compteurs selon le besoin).
- Enregistrez ce que les utilisateurs vivent et quand (au niveau de la minute c’est suffisant).
- Vérifiez si le problème est local à l’hôte ou à l’échelle de la flotte (Tâche 13).
- Si vous devez redémarrer quelque chose, faites‑le après avoir au moins une trace.
Checklist C : Transformer le triage en monitoring (pour arrêter de revivre le même incident)
- Créez une tâche planifiée qui exécute une courte capture
Get-Counterpendant les fenêtres de pointe. - Alertez sur des tendances, pas sur des points isolés :
- latence disque élevée et soutenue
- usage commit élevé et soutenu
- pagination soutenue avec faible mémoire disponible
- longueur de file CPU soutenue
- Revue hebdomadaire. Pas parce que c’est amusant. Parce que c’est moins cher que des pannes.
FAQ
1) Get‑Counter est‑il suffisamment précis pour la réponse aux incidents réels ?
Oui. Il lit la même infrastructure de compteurs de performance que PerfMon. Le mode d’échec habituel n’est pas la précision ; c’est l’interprétation (mauvais compteur, mauvaise instance, mauvais intervalle).
2) Dois‑je utiliser CookedValue ou RawValue ?
Utilisez CookedValue pour la plupart du travail opérationnel. RawValue sert quand vous implémentez vos propres calculs ou validez les types de compteurs. En triage production, privilégiez la clarté.
3) Quel intervalle d’échantillonnage devrais‑je utiliser ?
Pendant le triage : 1–2 secondes pour 30–120 échantillons. Pour la baseline : 5–15 secondes sur 10–30 minutes. Pour le trending long terme : 30–60 secondes suffit, en acceptant que vous manquerez les micro‑pics.
4) Pourquoi Get‑Counter à distance échoue quand WinRM fonctionne ?
Parce que les compteurs de performance et WinRM utilisent des canalisations différentes. Règles de pare‑feu, permissions, Remote Registry/dépendances de service ou politiques durcies peuvent bloquer la collecte même si vous pouvez exécuter PowerShell à distance.
5) « Avg. Disk sec/Read » est‑il identique à la latence disque ?
Pratiquement oui : c’est le temps moyen de service par lecture, en secondes, tel qu’observé par l’OS. Multipliez par 1000 pour penser en millisecondes. Surveillez à la fois lecture et écriture ; elles tombent en panne différemment.
6) Quelle est une « bonne » valeur de latence disque ?
Cela dépend du workload, mais heuristiquement : quelques millisecondes est sain pour beaucoup de charges serveur ; des dizaines de millisecondes sont préoccupantes ; des centaines constituent un incident. Comparez toujours à votre baseline.
7) Pourquoi le CPU semble bas alors que les utilisateurs ont des timeouts ?
Parce qu’attendre n’utilise pas le CPU. Les threads bloqués sur le disque, le réseau, des verrous ou la pagination ne brûlent pas de CPU. C’est pourquoi vous regardez la longueur de file, la pagination et la latence I/O ensemble.
8) Puis‑je utiliser Get‑Counter comme agent de monitoring léger ?
Oui, avec discipline. Gardez l’ensemble de compteurs réduit, des intervalles d’échantillonnage raisonnables, et des sorties structurées (BLG/CSV). Ne polluez pas des centaines de compteurs chaque seconde en production puis ne soyez pas surpris par l’overhead ajouté.
9) Comment éviter le problème du « mauvais nom d’instance » pour disques et processus ?
Énumérez d’abord les instances avec PathsWithInstances, puis échantillonnez les chemins exacts retournés. Pour les processus, préférez des métriques liées aux noms de service ou aux IDs quand c’est possible, car les noms d’instance peuvent changer.
Conclusion : prochaines étapes concrètes
- Choisissez vos compteurs clés (CPU total + file, mémoire disponible + commit + pagination, latence disque lecture/écriture par volume).
- Faites une capture de 2 minutes lors de la prochaine plainte au lieu de regarder le Gestionnaire des tâches. Sauvegardez‑la en BLG. Preuves d’abord, opinions ensuite.
- Établissez une baseline pour une fenêtre « normale et chargée » cette semaine. Sans baseline, vous devinez avec assurance.
- Transformez une leçon d’incident en alerte : latence disque soutenue, pression de commit soutenue ou longueur de file CPU soutenue. Choisissez celle qui correspond à votre dernière panne.
- Notez vos seuils comme heuristiques, pas comme des lois. Votre environnement vous apprendra ce que « mauvais » veut dire.
Si vous ne faites qu’une chose : commencez à mesurer régulièrement la latence disque et la pression de commit. Ces deux métriques détectent un nombre surprenant de tickets « serveur lent » avant qu’ils ne deviennent des pannes.