10.3 : Logging et transcript

Sophie referme le dossier sécurité de la formation sur une dernière question, revenue plusieurs fois depuis la section 6 sans jamais être vraiment traitée : « Un script planifié tourne seul, la nuit, sans personne pour le regarder. Le jour où quelque chose tourne mal, comment on sait exactement ce qu’il s’est passé ? » Cette dernière leçon répond à cette question : tracer ce qu’un script a réellement fait, et quand.

Start-Transcript : enregistrer une session complète

Start-Transcript capture tout ce qui s’affiche dans la console — commandes tapées, résultats, erreurs, avertissements — dans un fichier texte, du début à la fin de l’exécution :

Start-Transcript -Path "C:\Nordika\Logs\transcript-$(Get-Date -Format 'yyyyMMdd-HHmmss').txt"

Get-Service -Name "Spooler"
Write-Warning "Ceci sera aussi capturé"

Stop-Transcript

Ouvrez le fichier généré : vous y retrouverez non seulement les résultats, mais aussi l’horodatage précis de début et de fin, l’utilisateur sous lequel le script a tourné, et le nom de la machine — des informations précieuses en cas d’audit, bien au-delà de ce qu’un simple Write-Output redirigé vers un fichier pourrait fournir.

Point de vigilance : Start-Transcript capture ce qui s’affiche, mais pas nécessairement chaque valeur manipulée en coulisses dans le script. Un $resultat = Get-Service ... sans affichage explicite (Write-Output ou l’objet renvoyé implicitement, vu en 3.4) n’apparaîtra pas dans le transcript si la valeur n’est jamais montrée à l’écran ou renvoyée en sortie de la fonction englobante.

Intégrer le transcript dans un script planifié

En reprenant le script de supervision automatisé de la section 8, un transcript entoure l’ensemble de l’exécution, y compris la gestion d’erreurs déjà en place :

$logPath = "C:\Nordika\Logs\supervision-$(Get-Date -Format 'yyyyMMdd').txt"
Start-Transcript -Path $logPath -Append

try {
    # ... logique du script de supervision, vue en section 7 et 8
    Write-Output "Rapport généré avec succès"
} catch {
    Write-Warning "Échec du script : $($_.Exception.Message)"
} finally {
    Stop-Transcript
}

-Append évite d’écraser le fichier du jour si le script est relancé manuellement après un premier échec — chaque exécution s’ajoute à la suite dans le même fichier journalier, plutôt que de se substituer à la précédente.

Write-Verbose comme complément, pas comme substitut

Rappel de la leçon 3.4 : Write-Verbose permet d’ajouter du détail optionnel, invisible par défaut. Combiné à un transcript, il devient un outil de diagnostic précieux, activable seulement quand on en a besoin :

Start-Transcript -Path $logPath

Write-Verbose "Connexion au serveur SRV-01..." -Verbose
Get-Service -Name "Spooler" -ComputerName "SRV-01"

Stop-Transcript

Sans le -Verbose final, ce message resterait invisible, y compris dans le transcript — un bon compromis entre un journal exhaustif et un journal illisible à force de détails.

Le journal des événements Windows comme alternative

Pour une intégration plus poussée avec les outils de supervision déjà en place à Nordika (SIEM, centralisation de logs), on peut aussi écrire directement dans le journal d’événements Windows, plutôt que dans un simple fichier texte :

New-EventLog -LogName "Application" -Source "NordikaSupervision" -ErrorAction SilentlyContinue

Write-EventLog -LogName "Application" -Source "NordikaSupervision" -EventId 1001 -EntryType Information -Message "Rapport de supervision généré avec succès"

Retour d’expérience terrain : dans un environnement d’entreprise déjà équipé d’un outil de centralisation de logs (Splunk, ELK, Microsoft Sentinel…), écrire dans le journal d’événements Windows plutôt que dans un fichier texte isolé facilite grandement la corrélation avec d’autres événements du système — un incident réseau et l’échec d’un script de supervision devenant, par exemple, visibles côte à côte dans un même tableau de bord.

Nettoyer les logs anciens

Un transcript par exécution, cumulé sur des mois de fonctionnement, finit par occuper un espace disque conséquent — un ticket typique de maintenance, cohérent avec le script de nettoyage déjà écrit en leçon 4.2 :

Get-ChildItem "C:\Nordika\Logs" -Filter "*.txt" | 
    Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-90) } | 
    Remove-Item

Un exemple concret Nordika : le script de supervision, version finale et complète

En rassemblant tout ce qui a été construit depuis la section 7 — Remoting, gestion d’erreurs, email, secrets, signature, et maintenant le logging :

$logPath = "C:\Nordika\Logs\supervision-$(Get-Date -Format 'yyyyMMdd').txt"
Start-Transcript -Path $logPath -Append

try {
    $cleApi = Get-Secret -Name "ApiTicketingNordika" -AsPlainText
    $serveurs = Get-Content -Path "C:\Nordika\Scripts\serveurs.txt"

    $resultats = Invoke-Command -ComputerName $serveurs -ScriptBlock {
        $volume = Get-Volume -DriveLetter C
        [PSCustomObject]@{ 
            Serveur = $env:COMPUTERNAME
            EspaceLibrePourcent = [math]::Round(($volume.SizeRemaining / $volume.Size) * 100, 1) 
        }
    } -ErrorAction Stop

    $resultats | Format-Table -AutoSize
    Write-Output "Rapport généré avec succès pour $($resultats.Count) serveur(s)"

} catch {
    Write-Warning "Échec du script de supervision : $($_.Exception.Message)"
} finally {
    Stop-Transcript
}

Source officielle : la documentation Microsoft Start-Transcript et about_EventLogs (pour l’intégration au journal d’événements Windows) détaillent l’ensemble des options disponibles, notamment la limitation du transcript à certains flux uniquement (-IncludeInvocationHeader) pour affiner encore le niveau de détail capturé.

Cette leçon referme l’ensemble de la section sécurité de cette formation, de la 10.1 à aujourd’hui : ExecutionPolicy et signature garantissent qu’un script n’a pas été altéré, SecretManagement garantit qu’aucun secret n’y traîne en clair, et le logging garantit qu’on sait, a posteriori, exactement ce qu’il s’est passé. Trois piliers indépendants, indispensables ensemble pour tout script Nordika destiné à tourner sans surveillance directe.

Dans la prochaine leçon, un dernier TP pour clore cette section sécurité, avant le quiz final et la conclusion de toute la formation.