À 02:13, un serveur de fichiers est « lent », une équipe applicative est « bloquée » et vous regardez une machine Windows qui a l’air de patauger dans du sirop. Vous ouvrez une console, tapez quelque chose de simple par habitude, et ça marche — ou ça ne marche pas, parce que vous avez choisi le mauvais shell pour le moment.
Ce n’est pas une guerre de religion. C’est un choix d’outil sous pression. PowerShell est le bourrin moderne. CMD est le cafard de l’administration Windows : irritant par sa durabilité, difficile à tuer, et toujours présent dans les murs quand les lumières s’éteignent.
La vraie différence : objets vs texte (et pourquoi les ops s’en soucient)
CMD est un tuyau textuel. PowerShell est un pipeline d’objets. C’est le titre, mais ce sont les conséquences opérationnelles qui font monter la tension artérielle.
Le contrat de CMD : des chaînes de caractères partout
Dans CMD, presque tout ce que vous faites est « exécuter un programme, recevoir du texte, analyser le texte, en espérant que le texte ne change pas ». Certaines utilitaires sont intégrés (comme dir), d’autres sont des EXE classiques (comme ipconfig), et un nombre déprimant imprime « ce qu’il imprime ». C’est à la fois une limitation et une superpuissance : le texte est universel, et CMD est présent même quand la machine est à moitié cassée.
Le contrat de PowerShell : données structurées, puis mise en forme
PowerShell pousse des objets .NET, pas des chaînes, dans le pipeline. Les cmdlets émettent des objets avec des propriétés ; la mise en forme intervient à la fin. Cela signifie que vous pouvez filtrer de manière fiable (Where-Object), sélectionner des champs précisément (Select-Object), et exporter proprement (ConvertTo-Json, Export-Csv). Vous n’écrivez plus de regex pour trouver « le troisième jeton après les deux-points ». Vous n’avez plus peur de la localisation, des changements d’espaces ou des largeurs de colonnes.
Mais le modèle d’objets de PowerShell a un coût : temps de démarrage, chargement de modules, scripts de profil, restrictions de stratégie, et parfois le type d’échec où le shell est OK mais un module manque et votre commande « simple » se transforme en chasse aux dépendances.
Réalité des ops : choisissez le shell qui correspond à votre domaine de défaillance
- Si vous êtes en mode récupération, avec une interface limitée ou un environnement minimal : CMD fonctionne souvent quand PowerShell est absent ou handicapé.
- Si vous avez besoin de fiabilité à grande échelle, d’orchestration distante, d’inventaire ou de toute tâche répétable : PowerShell est le choix le plus sûr.
- Si vous effectuez un triage interactif rapide : l’un ou l’autre peut faire l’affaire, mais choisissez celui qui réduit la charge cognitive pour cette machine.
Une idée paraphrasée (pas textuellement) d’un co-auteur de Google SRE, Niall Murphy : « la fiabilité vient de la conception de systèmes qui échouent de façons prévisibles que vous avez répétées ». Le choix du shell fait partie de cet entraînement.
Quand CMD l’emporte encore
1) WinRE, le mode sans échec et « je ne peux pas charger mes joujoux »
Quand Windows est dans un environnement de récupération, vous voulez la plus petite surface d’attaque possible. CMD est disponible à plus d’endroits, avec moins de composants en jeu. Si la machine ne démarre pas, vous n’êtes pas là pour admirer les pipelines d’objets ; vous êtes là pour la faire démarrer.
2) Vous avez besoin des utilitaires classiques tels quels
Beaucoup de diagnostics Windows sont encore des EXE classiques : wevtutil, netsh, sc, robocopy, diskpart, bcdedit. PowerShell peut aussi les appeler, mais les règles de quoting de CMD correspondent souvent aux exemples que vous trouverez dans les runbooks et les anciens docs d’incident.
3) Le temps de démarrage compte (oui, parfois ça compte)
CMD s’ouvre rapidement, même sur un hôte stressé. PowerShell peut être rapide aussi, mais les modules, les profils et les contrôles d’endpoints en entreprise le rendent parfois lent. Quand vous itérez vite — testez un changement, relancez une vérification — la latence compte.
4) Les fichiers batch sont toujours partout (et certains sont critiques)
Si votre organisation a un glue de déploiement vieux de 15 ans, c’est probablement un fichier .bat ou .cmd utilisant if errorlevel et du parsing fragile. Le réécrire est parfois judicieux, mais ce n’est pas toujours le problème du jour.
5) Vous gérez des versions très anciennes de Windows ou des hôtes verrouillés
PowerShell 5.1 est courant, PowerShell 7 n’est pas universel, et certains serveurs durcis traitent PowerShell comme une arme chargée. CMD a tendance à être autorisé parce que c’est « juste un shell », ce qui est naïf mais pratique opérationnellement.
Blague courte #1 : CMD, c’est comme une boîte de vitesses manuelle : moins de fonctionnalités, plus de contrôle, et tout le monde jure qu’il sait la conduire jusqu’à la première cote.
Quand PowerShell l’emporte (la plupart du temps)
1) Tout ce qui implique des requêtes structurées
Si vous avez besoin de « tous les services qui sont Automatic mais pas Running » ou « tous les disques avec moins de 10% d’espace libre », PowerShell transforme ça en une commande unique et fiable. CMD transforme ça en parsing de sortie texte et espère que votre regex n’avale pas un espace.
2) Administration distante à l’échelle
PowerShell Remoting (WinRM / WSMan) vous donne une manière standard d’exécuter des commandes à distance, de vous authentifier correctement, et de renvoyer des résultats structurés. CMD peut faire de l’exécution distante via des outils tiers, des tâches planifiées, ou des astuces de l’époque WMI, mais PowerShell est l’option de première classe ici.
3) Automatisation plus sûre et idempotence
Quand vous écrivez du PowerShell avec discipline — paramètres explicites, gestion des erreurs, -WhatIf sur les cmdlets supportés, et journalisation cohérente — vous pouvez construire des opérations répétables. Le batch peut être répétable aussi, mais ses sémantiques d’échec sont un marécage : les codes de sortie se perdent, les pipelines cachent les échecs, et l’expansion différée est un cercle infernal particulier.
4) APIs de gestion Windows modernes
Les nouvelles surfaces de gestion apparaissent d’abord dans PowerShell : cmdlets CIM/WMI, cmdlets Storage, cmdlets Hyper-V, Defender et outils de sécurité, intégration d’agents cloud. CMD n’est pas le lieu d’innovation.
5) Sorties que vous pouvez intégrer à d’autres systèmes
Quand votre réponse à incident attend du JSON, ou que votre audit veut du CSV, PowerShell rend ça banal. CMD peut le faire, mais on dirait sculpter un violon à partir d’une palette d’expédition.
Blague courte #2 : Le pipeline PowerShell est génial jusqu’à ce que vous réalisiez que votre « one-liner » est devenu une nouvelle avec un rebondissement dans Select-Object.
Faits intéressants et contexte historique (les parties qui comptent encore)
- CMD descend de MS-DOS et du processeur de commandes NT ; c’est essentiellement l’interface d’administration la plus ancienne et toujours pertinente de Windows.
- PowerShell a commencé comme « Monad », conçu pour résoudre le problème du « parsing de texte comme API » en poussant des objets dans les pipelines.
- PowerShell est construit sur .NET, ce qui explique pourquoi vous pouvez atteindre des APIs système profondes (et pourquoi le démarrage et le chargement de modules peuvent être non triviaux).
- Built-ins de CMD vs programmes externes : des commandes comme
diretsetsont des built-ins du shell, tandis queipconfigest un exécutable — cela compte quand PATH est cassé. - Les utilitaires Windows ont souvent conservé des sorties stables pendant des décennies ; cette stabilité explique pourquoi tant de scripts fragiles fonctionnent encore.
- La stratégie d’exécution est devenue un champ de bataille en entreprise : les organisations l’ont utilisée comme contrôle, en comprenant parfois mal ce qu’elle empêche réellement.
- PowerShell 5.1 est « Windows PowerShell » (inclus sur de nombreux systèmes), tandis que PowerShell 7+ est la lignée multiplateforme « pwsh » — runtime différent, compatibilité de modules différente.
- WinRM était désactivé par défaut sur de nombreux postes clients pendant des années, ce qui a ralenti l’adoption du remoting et maintenu des habitudes de type « remote CMD ».
- Les bizarreries du batch sont des artefacts historiques : des choses comme les sémantiques
ERRORLEVELet l’expansion différée existent parce que la compatibilité était traitée comme un serment sacré.
Tâches pratiques : commandes, sorties et décisions (12+ exercices)
Ce sont volontairement des tâches « réelles d’ops » : des vérifications que vous lancez pendant des incidents, des migrations et des plaintes de performance étranges. Chaque tâche inclut une commande, une sortie typique, ce que ça signifie, et quelle décision cela entraîne.
Task 1: Identifier rapidement l’OS et le contexte de démarrage (CMD)
cr0x@server:~$ ver
Microsoft Windows [Version 10.0.17763.5458]
Ce que cela signifie : Confirme la famille de version Windows. Utile quand le comportement diffère entre Server 2012/2016/2019/2022.
Décision : Si vous êtes sur des builds plus anciens, attendez-vous à PowerShell plus ancien et à des cmdlets de stockage datés ; choisissez vos outils en conséquence.
Task 2: Vérifier le nom d’hôte et l’appartenance au domaine (CMD)
cr0x@server:~$ echo %COMPUTERNAME% & echo %USERDOMAIN%
FS-23
CORP
Ce que cela signifie : Vérification d’identité rapide ; confirme que vous n’êtes pas sur la mauvaise machine et si vous exécutez dans un contexte de domaine.
Décision : Si le domaine est incorrect ou vide, investiguez les problèmes de confiance/authentification avant de poursuivre « latency réseau ».
Task 3: Confirmer les droits élevés (CMD)
cr0x@server:~$ whoami /groups | findstr /i "S-1-5-32-544"
BUILTIN\Administrators Alias S-1-5-32-544 Mandatory group, Enabled by default, Enabled group
Ce que cela signifie : Vous faites partie du groupe Administrateurs local ; de nombreuses opérations stockage/réseau/service en ont besoin.
Décision : Si vous n’êtes pas élevé, relancez en tant qu’admin avant d’imputer « Access is denied » à une GPO ou un outil de sécurité.
Task 4: Vérifier la configuration IP et détecter les problèmes de « mauvaise NIC » (CMD)
cr0x@server:~$ ipconfig /all
Windows IP Configuration
Host Name . . . . . . . . . . . : FS-23
Primary Dns Suffix . . . . . . . : corp.example
Ethernet adapter Ethernet0:
DHCP Enabled. . . . . . . . . . : No
IPv4 Address. . . . . . . . . . : 10.40.12.23(Preferred)
Subnet Mask . . . . . . . . . . : 255.255.255.0
Default Gateway . . . . . . . . : 10.40.12.1
DNS Servers . . . . . . . . . . : 10.40.1.10
10.40.1.11
Ce que cela signifie : Confirme IP, gateway, DNS. « Preferred » suggère que la pile est satisfaite.
Décision : Si les serveurs DNS sont erronés ou manquants, corrigez la résolution de noms avant de creuser SMB ou les mystères AD.
Task 5: Vérification DNS rapide (CMD)
cr0x@server:~$ nslookup fileshare01
Server: dns01.corp.example
Address: 10.40.1.10
Name: fileshare01.corp.example
Address: 10.40.12.55
Ce que cela signifie : Le nom se résout, et vous savez quel serveur DNS a répondu.
Décision : Si ça time-out ou résout sur une IP inattendue, arrêtez. Corrigez le DNS ou les enregistrements obsolètes ; ne « optimisez » pas SMB.
Task 6: Validation rapide de la route (CMD)
cr0x@server:~$ route print | findstr /i "0.0.0.0"
0.0.0.0 0.0.0.0 10.40.12.1 10.40.12.23 25
Ce que cela signifie : La route par défaut pointe là où vous le pensez. La métrique montre la préférence.
Décision : Si la route par défaut est erronée (commun sur des serveurs multi-homed), corrigez le routage avant d’imputer des « timeouts aléatoires ».
Task 7: Mesurer la portée basique vs problèmes de chemin (CMD)
cr0x@server:~$ ping -n 4 10.40.12.55
Pinging 10.40.12.55 with 32 bytes of data:
Reply from 10.40.12.55: bytes=32 time<1ms TTL=128
Reply from 10.40.12.55: bytes=32 time<1ms TTL=128
Reply from 10.40.12.55: bytes=32 time<1ms TTL=128
Reply from 10.40.12.55: bytes=32 time<1ms TTL=128
Ping statistics for 10.40.12.55:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Ce que cela signifie : ICMP fonctionne ; la latence semble locale. Ce n’est pas la preuve que l’application fonctionne, mais ça réduit le périmètre.
Décision : Si perte de paquets existante, traitez-le comme un problème réseau jusqu’à preuve du contraire ; ne peaufinez pas des scripts PowerShell.
Task 8: Valider la connectivité SMB et l’état des sessions (CMD)
cr0x@server:~$ net use
New connections will be remembered.
Status Local Remote Network
-------------------------------------------------------------------------------
OK Z: \\fileshare01\dept Microsoft Windows Network
The command completed successfully.
Ce que cela signifie : Vous avez un lecteur mappé et il est actuellement OK.
Décision : Si les mappings échouent, vérifiez les identifiants et la synchronisation Kerberos avant de « redémarrer LanmanServer ».
Task 9: Vérifier l’espace disque rapidement (CMD)
cr0x@server:~$ wmic logicaldisk get name,freespace,size
FreeSpace Name Size
21474836480 C: 127999999488
1099511627776 D: 2199023255552
Ce que cela signifie : L’espace est en octets. C: a ~20 Go libres ; D: a ~1 To libre.
Décision : Si l’espace libre est faible sur le lecteur système, attendez-vous à des échecs de services, de patching, et des blocages d’écriture de logs. Nettoyez d’abord.
Task 10: Vérifier l’état d’un service rapidement (CMD)
cr0x@server:~$ sc query LanmanServer
SERVICE_NAME: LanmanServer
TYPE : 20 WIN32_SHARE_PROCESS
STATE : 4 RUNNING
WIN32_EXIT_CODE : 0 (0x0)
SERVICE_EXIT_CODE : 0 (0x0)
Ce que cela signifie : Le service serveur SMB est en cours d’exécution et ne reporte pas d’erreurs.
Décision : S’il est STOPPED ou instable, vous avez soit des dépendances en panne soit une famine de ressources ; pivotez vers les logs d’événements et la latence stockage.
Task 11: Interroger les événements système critiques récents (CMD, classique et fiable)
cr0x@server:~$ wevtutil qe System /q:"*[System[(Level=1 or Level=2)]]" /c:5 /f:text
Event[0]:
Log Name: System
Source: disk
Event ID: 7
Level: Error
Description:
The device, \Device\Harddisk2\DR2, has a bad block.
Ce que cela signifie : La couche disque rapporte des secteurs défectueux. Ce n’est pas « le réseau ». Ce n’est pas « PowerShell lent ». C’est le stockage.
Décision : Escaladez immédiatement vers le matériel/le stockage ; arrêtez d’ajuster la performance. Collectez les diagnostics SMART/fournisseur et planifiez un remplacement.
Task 12: Obtenir les processus gourmands en CPU (PowerShell)
cr0x@server:~$ powershell -NoProfile -Command "Get-Process | Sort-Object CPU -Descending | Select-Object -First 5 Name,Id,CPU,WorkingSet64"
Name Id CPU WorkingSet64
sqlservr 4216 9883 12728471552
MsMpEng 1712 622 398524416
svchost 1100 401 172425216
w3wp 5024 389 612978688
System 4 201 89579520
Ce que cela signifie : Le temps CPU est cumulatif depuis le démarrage du processus. WorkingSet64 est la mémoire en octets.
Décision : Si Defender (MsMpEng) est chaud pendant un incident sur un serveur de fichiers, envisagez des exclusions de scan pour des chemins à fort churn — prudemment, et avec approbation sécurité.
Task 13: Identifier les plus gros consommateurs mémoire (PowerShell)
cr0x@server:~$ powershell -NoProfile -Command "Get-Process | Sort-Object WorkingSet64 -Descending | Select-Object -First 5 Name,Id,@{n='WS_GB';e={[math]::Round($_.WorkingSet64/1GB,2)}}"
Name Id WS_GB
sqlservr 4216 11.85
w3wp 5024 0.57
MsMpEng 1712 0.37
explorer 3120 0.22
svchost 1100 0.16
Ce que cela signifie : Affiche le working set en Go. Utile pour un contrôle rapide : la machine swap-elle à mort ?
Décision : Si la pression mémoire est élevée et que le paging est suspecté, confirmez avec les compteurs perf avant de redémarrer des services à l’aveugle.
Task 14: Vérifier la santé et la topologie disque (cmdlets Storage PowerShell)
cr0x@server:~$ powershell -NoProfile -Command "Get-PhysicalDisk | Select-Object FriendlyName,MediaType,HealthStatus,OperationalStatus,Size"
FriendlyName MediaType HealthStatus OperationalStatus Size
NVMe0 SSD Healthy OK 1024 GB
SAS01 HDD Warning OK 4000 GB
SAS02 HDD Healthy OK 4000 GB
Ce que cela signifie : La pile stockage voit un disque en Warning. C’est souvent prédictif d’une défaillance, pas une fausse alerte.
Décision : Si un disque est Warning/Unhealthy, arrêtez l’optimisation et lancez la gestion de défaillance : vérifiez l’état RAID, le hot spare, la reconstruction, les sauvegardes.
Task 15: Mesurer rapidement des compteurs de performance SMB (PowerShell)
cr0x@server:~$ powershell -NoProfile -Command "Get-Counter '\SMB Server Shares(*)\Avg. sec/Read' -SampleInterval 1 -MaxSamples 3 | Select-Object -ExpandProperty CounterSamples | Select-Object Path,CookedValue"
Path CookedValue
\\FS-23\SMB Server Shares(dept)\Avg. sec/Read 0.0021
\\FS-23\SMB Server Shares(dept)\Avg. sec/Read 0.0019
\\FS-23\SMB Server Shares(dept)\Avg. sec/Read 0.0450
Ce que cela signifie : La latence de lecture est majoritairement correcte mais pique à 45ms sur un échantillon. Ça sent le backend stockage ou des drivers filtre.
Décision : Si les pics de latence corrèlent avec les plaintes utilisateurs, pivotez vers la file d’attente disque/latence et les drivers AV/filtre, pas les « flags de tuning SMB ».
Task 16: Vérifier la synchronisation horaire (Kerberos et « échecs d’auth mystérieux ») (CMD)
cr0x@server:~$ w32tm /query /status
Leap Indicator: 0(no warning)
Stratum: 4 (secondary reference - syncd by (S)NTP)
Precision: -23 (119.209ns per tick)
Last Successful Sync Time: 2/5/2026 1:52:10 AM
Source: dc01.corp.example
Poll Interval: 6 (64s)
Ce que cela signifie : La machine est synchronisée récemment et sur une source raisonnable.
Décision : Si l’heure dérive ou que la source est mauvaise, corrigez l’heure avant de chasser des « mauvais identifiants » et des « problèmes SPN ».
Task 17: Vérifier la préparation WinRM pour PowerShell remoting (CMD)
cr0x@server:~$ winrm quickconfig
WinRM service is already running on this machine.
WinRM is already set up for remote management on this computer.
Ce que cela signifie : Les bases du remoting sont configurées.
Décision : Si cela échoue, prévoyez un accès alternatif (RDP/console) ou corrigez le remoting avant de promettre « on peut l’exécuter sur 500 serveurs ».
Task 18: Obtenir la version et l’édition PowerShell installées (PowerShell)
cr0x@server:~$ powershell -NoProfile -Command "$PSVersionTable | Select-Object PSVersion,PSEdition"
PSVersion PSEdition
--------- ---------
5.1.17763.5458 Desktop
Ce que cela signifie : Il s’agit de Windows PowerShell 5.1 (édition Desktop), pas de PowerShell 7+ (Core).
Décision : N’assumez pas la compatibilité des modules multiplateformes ni une syntaxe moderne. Écrivez des scripts compatibles 5.1 ou déployez pwsh explicitement.
Mode d’emploi pour un diagnostic rapide : trouver rapidement le goulot d’étranglement
Voici la séquence que j’utilise quand quelqu’un dit « PowerShell est lent » ou « CMD est plus rapide » alors que le système s’étouffe sur autre chose. L’objectif est d’identifier la ressource limitante en quelques minutes, pas de gagner une argumentation.
Première étape : confirmer l’environnement et votre position
- Êtes-vous élevé ? Sinon, la moitié de vos vérifications mentiront par omission (ou échoueront simplement).
- Êtes-vous dans le bon shell et la bonne version ? PowerShell 5.1 vs 7 change la disponibilité des modules ; les profils peuvent ajouter des secondes de délai.
- L’hôte est-il lui-même suffisamment sain pour dépanner ? S’il manque d’espace sur C: ou de RAM, tous les outils semblent lents.
Deuxième étape : déterminer si c’est CPU, mémoire, disque ou réseau
- CPU : Cherchez un consommateur majeur qui correspond à la fenêtre de plainte (scans AV, compression, application incontrôlée).
- Mémoire : Un commit/paging élevé fait « bloquer » les shells pendant que le système thrash.
- Disque : Les pics de latence et la profondeur de file provoquent des blocages — en particulier le chargement de modules PowerShell et la lecture des profils.
- Réseau : Les stalls DNS et la détection automatique de proxy sont des coupables classiques pour « PowerShell lent » parce que beaucoup de commandes déclenchent la résolution de noms ou des vérifications de certificat.
Troisième étape : isoler le surcoût du shell du surcoût système
- Exécutez PowerShell avec
-NoProfilepour éliminer les profils et scripts lents. - Mesurez une cmdlet simple (comme
Get-Date) vs une cmdlet lourde en modules (comme stockage/réseau). Si les deux sont lents, ce n’est pas le module. - Appelez le même EXE depuis les deux shells (par ex.
ipconfig). S’il est lent dans les deux, incriminez le système ou les dépendances de l’EXE.
Quatrième étape : confirmer le chemin des dépendances (sur quoi votre commande attend-elle ?)
- DNS : une résolution lente peut bloquer des appels distants.
- Authentification : la dérive horaire ou la latence AD peut ralentir le remoting.
- Stockage : des lectures lentes bloquent tout, du import de modules aux requêtes de logs d’événements.
- Outils de sécurité : l’analyse de scripts et les hooks AMSI peuvent ajouter de la latence — parfois beaucoup.
Trois micro-histoires du monde de l’entreprise (douleur, regret, et une petite victoire)
Micro-histoire #1 : Un incident causé par une mauvaise hypothèse
L’équipe avait un runbook qui commençait par une vérité simple : « Utilisez PowerShell pour tout ». C’était une poussée de modernisation, et cela avait globalement payé. Donc, quand un contrôleur de domaine n’a pas démarré après un patch, l’ingénieur on-call a suivi le runbook — a ouvert PowerShell en recovery, tenté de charger les outils habituels, et buté. L’environnement n’avait pas ce que le runbook supposait.
Ils ont perdu du temps à tenter de monter des modules et exécuter des cmdlets qui n’étaient pas présents. Pendant ce temps, le besoin réel était basique : inspecter la configuration de démarrage, confirmer les lettres de volumes dans WinRE (qui aiment changer), et revenir sur un mauvais pilote. CMD aurait fait tout cela avec des built-ins et des utilitaires classiques.
Finalement, un senior est arrivé, a demandé « dans quel shell êtes-vous ? » et est passé à CMD. Ils ont utilisé bcdedit et des opérations de fichiers basiques pour valider les entrées de boot et repérer le décalage entre la cartographie de volumes attendue et réelle. Ensuite, c’était mécanique : corriger la référence de démarrage, confirmer la bonne ruche système, redémarrer.
Le postmortem n’était pas sur PowerShell qui serait mauvais. C’était sur l’hypothèse de la présence de votre environnement préféré au moment exact où vous avez besoin de la chaîne de dépendances la plus courte. La correction a été simple et ennuyeuse : le runbook a reçu une branche « Recovery mode » qui par défaut utilise CMD et liste les quelques commandes qui fonctionnent vraiment dans ce contexte.
Micro-histoire #2 : Une optimisation qui a mal tourné
Un groupe plateforme voulait une collecte de logs plus rapide en incident. Ils avaient un script PowerShell qui interrogeait les journaux d’événements, filtrait par période, et exportait le résultat en JSON pour un outil interne. C’était correct, mais pas assez rapide quand on le lançait sur beaucoup d’hôtes.
Ils ont donc « optimisé » en remplaçant les requêtes structurées d’événements par une approche qui semblait plus rapide : appeler wevtutil depuis PowerShell et parser le texte. Ça a bien benchmarké sur quelques machines. Ils l’ont déployé.
Deux mois plus tard, pendant une panne, le collecteur a produit des résultats vides pour un lot de serveurs dans un autre paramétrage régional. La sortie texte avait un format légèrement différent. La regex n’a pas matché. L’équipe d’incident a perdu du temps car le tableau de bord indiquait « pas d’erreurs », alors que les serveurs hurlaient dans le journal Système.
Ils sont revenus à l’approche objet puis ont optimisé correctement : réduire la portée des requêtes, utiliser le filtrage côté serveur quand possible, et batcher les appels distants. La leçon : les hacks de performance qui échangent la structure contre la vitesse de parsing se retournent souvent contre vous, et toujours au pire moment — quand vous avez besoin que les données soient non ambiguës.
Micro-histoire #3 : Une pratique ennuyeuse mais correcte qui a sauvé la mise
Une autre entreprise, une autre flotte Windows axée stockage. Leurs serveurs de fichiers étaient stables, mais l’équipe avait l’habitude suivante : chaque serveur disposait d’un petit « kit de triage » documenté dans un fichier texte local et imprimé dans le système de runbooks. Il incluait des commandes CMD et PowerShell, chacune choisie pour l’environnement où elle est la plus fiable.
Pendant un incident proche d’un ransomware, les contrôles de sécurité se sont resserrés rapidement. L’exécution de scripts PowerShell a été très restreinte, et certains outils distants ont été bloqués par des changements de politique. Les SREs on-call pouvaient encore se connecter, mais beaucoup de chemins d’automatisation étaient coupés.
Le kit de triage s’en fichait. Il reposait sur des vérifications locales directes : état de service avec sc, réseau avec ipconfig et route, échantillonnage de journaux avec wevtutil, et contrôles santé stockage avec PowerShell lancé en mode -NoProfile pour un minimum d’overhead. Ils ont pu déterminer quels hôtes étaient impactés, lesquels étaient sains, et où se situait le goulot (latence disque et drivers filtre) sans combattre la couche politique.
Pas d’héroïsme. Pas de créativité. Juste une séquence de diagnostic minimale et répétée qui marche sous pression. C’est ce type d’ennui que vous voulez.
Erreurs courantes : symptôme → cause racine → correctif
1) « PowerShell est lent à s’ouvrir »
Symptôme : La console s’ouvre mais met plusieurs secondes avant d’accepter la saisie.
Cause racine : Scripts de profil lourds, chargement automatique de modules, ou scanning par les outils de sécurité des chemins de profil/modules.
Correctif : Utilisez powershell -NoProfile pour le travail en incident. Auditez le contenu de $PROFILE et retirez les imports coûteux. Si des outils de sécurité scannent les scripts, coordonnez des exclusions pour des scripts d’administration connus — pas des exceptions larges.
2) « Mon script marche en PowerShell mais échoue en CMD »
Symptôme : Les commandes avec quotes et parenthèses se comportent différemment ; les variables ne sont pas développées.
Cause racine : Règles différentes de quoting et d’expansion des variables. CMD utilise %VAR% et a des pièges d’expansion différée ; PowerShell utilise $var et traite les chaînes différemment.
Correctif : Ne collez pas de la syntaxe PowerShell dans CMD ou l’inverse. Si vous devez appeler un shell depuis l’autre, soyez explicite et gardez les arguments simples.
3) « Le pipeline CMD n’a pas échoué, mais la tâche n’a pas fonctionné »
Symptôme : Le batch continue même après l’échec d’une commande ; les logs montrent des textes de succès approximatifs.
Cause racine : Codes de sortie perdus dans les pipelines ou écrasés par des commandes suivantes ; mauvais usage de ERRORLEVEL.
Correctif : Vérifiez if errorlevel 1 immédiatement après la commande. Évitez de pipe quand vous avez besoin d’un code de sortie précis. Envisagez d’encapsuler des étapes critiques en PowerShell où la gestion d’erreurs est plus contrôlable.
4) « Le remoting PowerShell échoue, mais le RDP fonctionne »
Symptôme : Enter-PSSession ou Invoke-Command échouent avec des erreurs d’accès/transport.
Cause racine : WinRM non configuré, règles de pare-feu manquantes, problèmes SPN/Kerberos, ou délégation contrainte.
Correctif : Validez la config WinRM localement avec winrm quickconfig. Confirmez DNS et synchronisation horaire. Vérifiez la politique de pare-feu. Si la politique d’entreprise bloque WinRM, utilisez des méthodes de remoting alternatives approuvées et documentez-les.
5) « Le parsing texte a cassé après un patch »
Symptôme : Un script batch qui scrappe la sortie de net/sc/wevtutil renvoie soudain des données vides.
Cause racine : Le format de sortie a changé subtilement ; les paramètres régionaux diffèrent ; les colonnes se réorganisent.
Correctif : Arrêtez de parser des sorties destinées à des humains quand c’est possible. En PowerShell, utilisez des cmdlets qui renvoient des objets. Si vous devez parser, contraignez la locale et utilisez des formats stables (CSV/JSON) quand disponibles.
6) « PowerShell dit accès refusé même en admin »
Symptôme : Un utilisateur admin peut lancer des outils CMD mais des cmdlets PowerShell échouent.
Cause racine : Problèmes de token UAC, Constrained Language Mode, politiques AppLocker/WDAC, ou privilèges manquants dans le contexte du processus.
Correctif : Vérifiez l’élévation, contrôlez le language mode, et testez avec -NoProfile. Si des politiques de contrôle applicatif sont en place, travaillez avec la sécurité pour approuver des scripts signés et des binaires administratifs connus.
Listes de contrôle / plan pas à pas
Checklist : choisir CMD vs PowerShell sur le moment
- Êtes-vous en WinRE/Safe Mode/environnement minimal ? Préférez CMD.
- Avez-vous besoin de filtrage/rapport/export structuré ? Préférez PowerShell.
- Le système est-il instable (erreurs disque, pression mémoire) ? Privilégiez la voie la moins coûteuse en dépendances : CMD + EXE ciblés, et PowerShell uniquement avec
-NoProfile. - Travaillez-vous à distance sur beaucoup d’hôtes ? Préférez le remoting PowerShell, mais vérifiez WinRM et la politique d’abord.
- La tâche est-elle intrinsèquement un utilitaire classique ? Utilisez l’utilitaire directement ; ne l’encapsulez pas sauf si vous avez vraiment besoin de structure et que le parsing restera fiable.
Pas à pas : construire un runbook « deux shells » qui survit aux incidents
- Rédigez chaque vérification critique deux fois : une méthode compatible CMD, une méthode PowerShell. Choisissez l’autoritative et étiquetez le fallback.
- Standardisez l’invocation PowerShell : utilisez
-NoProfiledans les runbooks sauf si une fonctionnalité de profil est explicitement nécessaire. - Journalisez les sorties brutes pour la forensique : stockez la commande exacte et la sortie dans le ticket/notes d’incident.
- Définissez un ensemble diagnostique minimum : identité, synchronisation horaire, DNS, route, espace disque libre, erreurs de journaux, santé des services.
- Entraînez-vous en modes dégradés : testez le runbook sur une VM en Safe Mode ou en simulation « disque plein ». C’est là que les hypothèses meurent.
- Ayez un déclencheur d’escalade : « Si le disque montre Warning/Unhealthy ou le journal Système a des erreurs disque, arrêtez et engagez le stockage/matériel. »
Pas à pas : réécrire un job batch fragile en PowerShell sans casser la production
- Geler le comportement : capturez les entrées/sorties et les codes de sortie actuels. Si vous ne savez pas à quoi ressemble le « succès », vous enverrez une régression.
- Remplacez le parsing en premier : passez du scraping de texte aux requêtes d’objets quand c’est possible.
- Rendez les erreurs évidentes : activez une gestion stricte des erreurs dans le script et renvoyez des codes de sortie significatifs aux appelants.
- Déployez côte à côte : exécutez la version PowerShell en « observe » pendant que le batch effectue toujours le travail réel.
- Basculez progressivement : petit ensemble de serveurs d’abord ; comparez les résultats.
- Documentez le rollback : en ops, le rollback est une fonctionnalité, pas une confession d’échec.
FAQ
1) CMD est-il obsolète ?
Non. Il est vieux, pas mort. CMD reste la base la plus fiable quand Windows est dans un état réduit, et beaucoup d’utilitaires cœur sont encore des outils « époque CMD ».
2) Dois-je arrêter d’écrire des fichiers batch ?
Pour l’automatisation nouvelle : oui, en grande partie. Utilisez PowerShell pour tout ce qui requiert correction, structure et maintenabilité. Conservez le batch pour du glue dans des environnements contraints et pour l’intégration legacy quand réécrire introduit un risque.
3) Pourquoi PowerShell semble-t-il parfois plus lent même lorsque la commande est simple ?
Les frais de démarrage (profils, découverte de modules), le scanning de sécurité, et l’initialisation .NET peuvent dominer les opérations « simples ». Utilisez -NoProfile pour le travail en incident et évitez la personnalisation lourde des profils sur les serveurs.
4) PowerShell peut-il exécuter des commandes CMD ?
Oui — PowerShell peut exécuter n’importe quel exécutable. Mais faites attention au quoting et aux commandes qui sont des built-ins du shell (comme dir), que PowerShell peut aliaser ou interpréter différemment.
5) Quelle est la plus grande différence pratique en scripting ?
La gestion des erreurs et les types de données. PowerShell vous permet de travailler avec des objets structurés et de gérer les exceptions. Le batch vous force souvent à inférer l’état à partir de texte et de codes de sortie, ce qui est plus fragile.
6) Le remoting PowerShell est-il toujours la meilleure option distante ?
C’est l’option native Windows la plus propre quand WinRM est disponible et que la politique l’autorise. Dans les environnements verrouillés, vous pouvez avoir besoin de méthodes alternatives approuvées. L’erreur est de supposer que le remoting est activé partout.
7) Ai-je besoin de PowerShell 7 ?
Pas nécessairement. Beaucoup de modules d’administration Windows ciblent 5.1. PowerShell 7 est excellent pour les scripts cross-plateforme et des améliorations de performance, mais la compatibilité des modules et la réalité du déploiement en entreprise comptent.
8) Comment éviter le piège « script PowerShell bloqué par la politique » pendant les incidents ?
Ayez un plan qui ne dépend pas de scripts non signés exécutés ad hoc. Utilisez des scripts signés pour l’automatisation standardisée, gardez un fallback CMD pour le triage de base, et documentez comment exécuter PowerShell avec des dépendances minimales.
9) Le parsing de sortie texte est-il toujours mauvais ?
Non, juste risqué. En urgence, le parsing texte peut être pragmatique. Pour l’automatisation durable, préférez les sorties structurées et les requêtes basées sur des objets, car « ça marche aujourd’hui » n’est pas une stratégie de fiabilité.
Prochaines étapes applicables
Arrêtez de demander « Quel shell est meilleur ? » Demandez « Quel shell échoue le moins pour ce scénario ? » PowerShell devrait être votre défaut pour l’automatisation, le reporting et l’échelle. CMD doit rester votre secours pour la récupération, les environnements minimaux, et ces utilitaires classiques qui racontent encore la vérité quand tout le reste brûle.
Faites ceci ensuite :
- Créez un kit de triage deux-shells pour vos rôles serveurs centraux (fichiers, web, BD, contrôleurs de domaine). Gardez-le court et exécutable.
- Standardisez l’utilisation PowerShell en incident :
-NoProfile, paramètres explicites et sorties propres. - Éliminez progressivement le parsing fragile : remplacez le scraping texte par des requêtes d’objets, mais ne « optimisez » pas en rendant vos données moins fiables.
- Entraînez-vous en modes dégradés : WinRE, disque plein, politiques restreintes. C’est là que CMD gagne encore ses galons.
Si vous faites ces quatre choses, vous passerez moins de temps à vous battre avec vos outils et plus de temps à réparer le système. Ce qui est le travail, après tout.