Skip to content

Module 6 — GĂ©rer un incident AD : procĂ©dures "break-glass"

Durée: 1h00 | Prérequis: Modules 1-5 complétés

Objectif

À la fin de ce module, vous saurez rĂ©agir de façon structurĂ©e Ă  un incident PowerShell AD qui part en vrille — sans aggraver la situation.


Quand un script se passe mal

Les incidents critiques arrivent rarement à un moment pratique. Statistiquement, ils surviennent en fin de journée, en fin de semaine, ou pendant l'absence du responsable. La cause principale est rarement matérielle : c'est presque toujours un script PowerShell mal validé.

Trois rÚgles pour éviter d'empirer les choses :

  • La panique est plus dangereuse que l'incident lui-mĂȘme.
  • La mĂ©moire dĂ©faille sous stress, donc on documente immĂ©diatement.
  • Tenter de rĂ©parer seul Ă  chaud est la deuxiĂšme cause d'aggravation.

Les 10 étapes d'une procédure structurée

1. ArrĂȘter et respirer (30 secondes)

ArrĂȘt total de l'activitĂ©. Mettre les notifications en sourdine. Prendre quelques secondes pour redescendre. La panique mĂšne aux mauvaises dĂ©cisions, qui mĂšnent Ă  des dĂ©gĂąts plus larges.

2. Évaluer l'impact (2 minutes)

Questions Ă  se poser :

  • Combien d'utilisateurs affectĂ©s ?
  • Quels services sont indisponibles ?
  • DonnĂ©es perdues ou seulement inaccessibles ?
  • Quelle fenĂȘtre de rĂ©cupĂ©ration est disponible ?

Commandes de diagnostic rapide :

Get-ADDomain | Select-Object DNSRoot, DomainMode                 # domaine OK ?
Get-ADUser -Filter * -ResultSetSize 10 | Select-Object Name, Enabled    # users OK ?
Get-ADGroup -Filter {Name -like "GG-*"} -ResultSetSize 5         # groupes OK ?

3. Documenter immédiatement (1 minute)

echo "INCIDENT $(date): $(whoami) sur $(hostname)" > incident.log
echo "Commande exécutée: [copier exactement]" >> incident.log
echo "Erreur obtenue: [copier exactement]" >> incident.log
echo "Impact observé: [décrire]" >> incident.log

La mémoire défaille sous stress. Le document est la seule source fiable une heure plus tard.

4. Ne pas réparer seul (30 secondes)

À Ă©viter :

  • "Je vais vite corriger ça."
  • "Personne n'a besoin de savoir."
  • "Un autre script va arranger ça."
  • "Je peux rollback rapidement."

À faire :

  • Alerter le superviseur immĂ©diatement.
  • Documenter avant de toucher quoi que ce soit.
  • Demander de l'aide avant d'aggraver.

5. Vérifier les sauvegardes (2 minutes)

# Quoi vérifier:
# - Sauvegarde AD récente ?
# - System State backup ?
# - Snapshots VMware ?
# - Réplication fonctionnelle ?

Get-WinEvent -LogName "Directory Service" -MaxEvents 10

6. Isoler le problĂšme (3 minutes)

Identifier précisément le périmÚtre affecté.

$impactedOU = "OU=RH,OU=EU,DC=maxtec,DC=be"

# État actuel
Get-ADUser -Filter * -SearchBase $impactedOU -Properties Enabled |
    Group-Object Enabled |
    Select-Object Name, Count

# Comparaison avec une OU non affectée
Get-ADUser -Filter * -SearchBase "OU=IT,OU=EU,DC=maxtec,DC=be" -Properties Enabled |
    Group-Object Enabled |
    Select-Object Name, Count

7. Communiquer (2 minutes)

À: superviseur@maxtec.be, equipe-it@maxtec.be
Sujet: INCIDENT AD - $(date)

RÉSUMÉ
- Heure: $(Get-Date)
- Admin: $(whoami)
- Impact: [X utilisateurs / Y services]
- Cause: Script PowerShell [nom]

EN COURS
- Évaluation impact
- Vérification backups
- Équipe alertĂ©e
- Réparation en attente de validation

BESOIN
- Validation approche de récupération
- Autorisation procédure break-glass

Prochaine mise Ă  jour: dans 15 minutes

8. Préparer le plan de récupération (5 minutes)

Pour un cas typique — utilisateurs dĂ©sactivĂ©s par erreur :

# Plan A: réactivation sélective
$affectedUsers = Get-ADUser -Filter {Enabled -eq $false} `
                  -SearchBase "OU=RH,OU=EU,DC=maxtec,DC=be" `
                  -Properties WhenChanged |
    Where-Object { $_.WhenChanged -gt (Get-Date).AddHours(-1) }

# Plan B: restauration depuis backup
#   Temps estimé: 2-4h
#   Impact: perte des données des derniÚres 24h
#   Validation nécessaire

# Plan C: reconstruction manuelle
#   Temps estimé: 6-8h
#   Ressources: équipe complÚte
#   Risque: erreurs humaines

9. Valider avant d'exécuter

# Toujours tester sur un échantillon réduit d'abord
$testUser = $affectedUsers | Select-Object -First 1
Set-ADUser -Identity $testUser.SamAccountName -Enabled $true -WhatIf

# Puis procéder par lots, en vérifiant chaque action
foreach ($user in ($affectedUsers | Select-Object -First 5)) {
    Write-Host "Réactivation: $($user.Name)"
    Set-ADUser -Identity $user.SamAccountName -Enabled $true

    $check = Get-ADUser -Identity $user.SamAccountName -Properties Enabled
    if ($check.Enabled) {
        Write-Host "  OK: $($user.Name)" -ForegroundColor Green
    } else {
        Write-Host "  ÉCHEC: $($user.Name)" -ForegroundColor Red
        break   # ArrĂȘter dĂšs qu'un cas Ă©choue
    }
}

10. Post-mortem (15 minutes)

Pas pour blñmer — pour apprendre.

## INCIDENT REPORT - $(date)

### Timeline
- 17:02: Script exécuté
- 17:05: Erreur détectée
- 17:06: Incident déclaré
- 17:15: Impact évalué
- 17:45: Récupération commencée
- 18:30: Service restauré

### Root cause
- Script source: [URL/fichier]
- Erreur: absence de -WhatIf sur commande critique
- Validation manquée: filtre trop large

### Impact
- Utilisateurs affectés: X
- Services down: Y
- Durée: Z minutes

### Corrective actions
- [ ] Mise à jour procédure validation scripts
- [ ] Formation équipe sur -WhatIf obligatoire
- [ ] Amélioration systÚme backup
- [ ] Script review process

### Lessons learned
- -WhatIf n'est jamais optionnel
- Pression temps ≠ excuse pour skip validation
- Documentation incident = crucial

Simulation en classe — vendredi 17h12

Email reçu :

De: marie.dubois@maxtec.be
À: admin@maxtec.be
Sujet: URGENT - Plus personne ne peut se connecter Ventes

Toute l'équipe Ventes est bloquée !
Réunion client dans 30 minutes !

Jeu de rĂŽle

Instructeur : admin en panique. Étudiants : Ă©quipe d'urgence appelĂ©e.

Phase 1 — Calme initial (2 min)

Admin   : "J'ai exécuté un script et maintenant..."
Équipe  : [Étape 1] "Stop. Respirer. Que s'est-il passĂ© exactement ?"

Phase 2 — Investigation (5 min)

Équipe  : [Étapes 2-3] "Montrez le script et l'erreur."
Admin   : "Je voulais ajouter un utilisateur Ă  un groupe..."

Script du désastre :

# Intention
Add-ADGroupMember -Identity "GG-EU-Ventes-Users" -Members "nouvel.employe"

# Exécuté (typo + chaßne mal pensée)
Remove-ADGroupMember -Identity "GG-EU-Ventes-Users" `
    -Members (Get-ADGroupMember -Identity "GG-EU-Ventes-Users")
# Remove au lieu de Add, et on retire tous les membres existants

Phase 3 — Plan d'action (3 min)

Équipe : [Étapes 4-8]
- "Pas de panique : le groupe est vidé, mais les utilisateurs existent toujours."
- "Backup AD de ce matin disponible ?"
- "Liste des membres disponible ailleurs (export précédent) ?"
- "On commence par identifier qui était dans le groupe."

Kit d'urgence — scripts

Diagnostic rapide

# diagnostic-urgence-ad.ps1
param($SearchBase = "OU=EU,DC=maxtec,DC=be")

Write-Host "=== DIAGNOSTIC URGENCE AD ===" -ForegroundColor Red

Write-Host "`n1. ÉTAT DOMAINE:" -ForegroundColor Yellow
Get-ADDomain | Select-Object DNSRoot, DomainMode, InfrastructureMaster

Write-Host "`n2. CONTRÔLEURS:" -ForegroundColor Yellow
Get-ADDomainController -Filter * | Select-Object Name, IPv4Address, OperatingSystem

Write-Host "`n3. ÉCHANTILLON UTILISATEURS:" -ForegroundColor Yellow
Get-ADUser -Filter * -SearchBase $SearchBase -ResultSetSize 10 |
    Select-Object Name, Enabled, LastLogonDate |
    Format-Table -AutoSize

Write-Host "`n4. GROUPES CRITIQUES:" -ForegroundColor Yellow
$groupesCritiques = @("Admins du domaine", "GG-EU-IT-Admin", "GG-EU-Ventes-Users")
foreach ($groupe in $groupesCritiques) {
    try {
        $membres = Get-ADGroupMember -Identity $groupe -ErrorAction Stop
        Write-Host "  OK   - $groupe : $($membres.Count) membres" -ForegroundColor Green
    } catch {
        Write-Host "  FAIL - $groupe : $($_.Exception.Message)" -ForegroundColor Red
    }
}

Write-Host "`n5. ÉVÉNEMENTS RÉCENTS:" -ForegroundColor Yellow
Get-WinEvent -LogName Security -MaxEvents 5 |
    Where-Object { $_.Id -in @(4728, 4729, 4756, 4757) } |
    Select-Object TimeCreated, Id, LevelDisplayName, Message |
    Format-Table -Wrap

Récupération d'un groupe vidé

# recuperation-groupe-vide.ps1
param(
    [Parameter(Mandatory)]
    [string]$GroupName,

    [switch]$WhatIf = $true
)

Write-Host "=== RÉCUPÉRATION GROUPE VIDÉ ===" -ForegroundColor Cyan
Write-Host "Groupe: $GroupName" -ForegroundColor Yellow
Write-Host "Mode: $($WhatIf ? 'SIMULATION' : 'RÉEL')" -ForegroundColor $(if ($WhatIf) { 'Yellow' } else { 'Red' })

# 1. Vérifier l'état actuel du groupe
try {
    $groupe = Get-ADGroup -Identity $GroupName -ErrorAction Stop
    $membres = Get-ADGroupMember -Identity $GroupName -ErrorAction Stop

    if ($membres.Count -gt 0) {
        Write-Host "Attention: le groupe n'est pas vide ($($membres.Count) membres)" -ForegroundColor Yellow
        $membres | Select-Object Name | Format-Table
        $continuer = Read-Host "Continuer ? (oui/non)"
        if ($continuer -ne "oui") { exit }
    }
} catch {
    Write-Error "Groupe $GroupName introuvable: $($_.Exception.Message)"
    exit
}

# 2. Chercher dans les logs récents les anciens membres
Write-Host "`nRecherche dans les logs..." -ForegroundColor Yellow

$evenements = Get-WinEvent -LogName Security -MaxEvents 100 |
    Where-Object {
        $_.Id -eq 4729 -and
        $_.Message -match $GroupName -and
        $_.TimeCreated -gt (Get-Date).AddHours(-2)
    }

if ($evenements) {
    Write-Host "ÉvĂ©nements de suppression trouvĂ©s:" -ForegroundColor Green
    $evenements | ForEach-Object {
        Write-Host "  $($_.TimeCreated): $($_.Message)" -ForegroundColor Cyan
    }
} else {
    Write-Host "Aucun événement récent trouvé." -ForegroundColor Red
    Write-Host "Alternatives:" -ForegroundColor Yellow
    Write-Host "  - Restaurer depuis backup AD"
    Write-Host "  - Reconstruction manuelle"
    Write-Host "  - Consulter la documentation métier"
}

Contacts d'urgence — maxtec.be

Niveau 1 — Support local
  Admin principal: richard@maxtec.be
  Backup: irene@maxtec.be

Niveau 2 — Management IT
  Responsable IT: responsable.it@maxtec.be
  Astreinte: +33 6 XX XX XX XX

Niveau 3 — Direction (impact business critique uniquement)
  DG: directeur.general@maxtec.be
  DRH: marie.dubois@maxtec.be

Services externes
  Consultant AD urgence: SociĂ©tĂ©X (+33 1 AA AA AA AA, 200€/h, intervention 2h)
  Service backup: BackupCorp (+33 8 BB BB BB BB, SLA 4h)

Checklist — premiùres minutes

Phase critique (5 premiĂšres minutes)

  • Stop. Respirer 30 secondes.
  • Noter l'heure exacte de l'incident.
  • Copier la commande qui a causĂ© le problĂšme.
  • Copier le message d'erreur exact.
  • Évaluer le nombre d'utilisateurs impactĂ©s.
  • Alerter le superviseur si impact > 10 utilisateurs.
  • Ne pas essayer de rĂ©parer seul.

Phase récupération (aprÚs validation)

  • Tester la solution sur 1 utilisateur d'abord.
  • ProcĂ©der par lots de 5 maximum.
  • VĂ©rifier chaque action avant la suivante.
  • Documenter chaque Ă©tape.
  • Tenir l'Ă©quipe informĂ©e toutes les 15 minutes.
  • PrĂ©parer le post-mortem dĂšs rĂ©solution.

Récapitulatif

Cinq principes :

  1. Panique = ennemi principal — elle aggrave systĂ©matiquement la situation.
  2. Documentation = survie — la mĂ©moire dĂ©faille sous stress.
  3. L'Ă©quipe est une ressource — l'ego individuel est une faiblesse.
  4. Valider mĂȘme en urgence — pas d'exception.
  5. Post-mortem pour apprendre, pas pour blĂąmer.

Mantra : stop — respirer — documenter — demander de l'aide — valider — agir.


Fin du cours

Ce que vous maĂźtrisez maintenant :

  1. Une approche réaliste du travail PowerShell AD en 2025.
  2. Les commandes essentielles du support niveau 1 et 2.
  3. L'utilisation professionnelle d'une IA comme copilote.
  4. La détection des scripts dangereux.
  5. Le réflexe -WhatIf systématique.
  6. Une procédure structurée en cas d'incident.

Pour le lundi qui suit :

  • Appliquer -WhatIf systĂ©matiquement.
  • Valider chaque script trouvĂ© en ligne avant exĂ©cution.
  • Documenter les actions importantes.
  • Partager ces rĂ©flexes avec les collĂšgues.