3. Automatiser une tâche complète

Construire un script robuste : entrée → traitement → sortie + log.
Objectifs
  • Structurer un script en 4 phases : entrée, contrôle, traitement, sortie
  • Implémenter un mode Audit (sans action) et un mode Action (avec modifications)
  • Produire une sortie exploitable : affichage + fichier de rapport + log horodaté
Contexte

Cas courant TSSR : organiser un dossier “source” en rangeant les fichiers par extension (TXT, LOG, CSV, etc.). Le script doit être réutilisable, sécurisé, et laisser une trace (log).

Commandes utiles

Entrée & contrôle

  • Read-Host demander un chemin
  • Test-Path vérifier existence
  • Get-Location contexte courant

Traitement

  • Get-ChildItem lister fichiers
  • New-Item créer dossiers
  • Move-Item déplacer fichiers

Sortie & traçabilité

  • Out-File écrire un rapport (écrase)
  • Add-Content écrire un log (append)
  • Get-Date horodatage
Principe exploitation : un script doit pouvoir tourner plusieurs fois sans casser l’existant et sans modifier en mode audit.
Script complet

Script : Ranger un dossier par extension (avec mode audit/action + logs)

Le script ci-dessous : 1 demande un dossier, 2 contrôle le chemin, 3 prépare un rapport + un log, 4 traite chaque fichier.

# =========================
# Entrée
# =========================
$sourceDir = Read-Host "Chemin du dossier à organiser (ex: C:\Temp\source)"
$mode      = Read-Host "Mode : 1=Audit  2=Action"

# =========================
# Contrôles
# =========================
if (-not (Test-Path $sourceDir)) {
  Write-Output "Dossier introuvable : $sourceDir"
  Write-Output "Dossier courant : $(Get-Location)"
  return
}

if ($mode -ne "1" -and $mode -ne "2") {
  Write-Output "Mode invalide : $mode (attendu 1 ou 2)"
  return
}

# =========================
# Sorties (rapport + log)
# =========================
$reportPath = Join-Path $sourceDir "report.txt"
$logPath    = Join-Path $sourceDir "script.log"

function Write-Log {
  param(
    [string]$Message,
    [ValidateSet("INFO","WARN","ERROR")][string]$Level = "INFO"
  )
  $ts = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
  Add-Content -Path $logPath -Value "$ts [$Level] $Message"
}

"RAPPORT - Organisation du dossier : $sourceDir" | Out-File $reportPath -Encoding UTF8
Write-Log "Démarrage script - Mode=$mode - Source=$sourceDir"

# =========================
# Traitement
# =========================
$files = Get-ChildItem -Path $sourceDir -File

foreach ($f in $files) {

  # Déterminer le dossier cible (par extension)
  $ext = $f.Extension
  if ([string]::IsNullOrWhiteSpace($ext)) { $ext = "SANS_EXTENSION" }
  else { $ext = $ext.TrimStart(".").ToUpper() }

  $targetDir = Join-Path $sourceDir $ext

  # Créer le dossier cible si besoin
  if (-not (Test-Path $targetDir)) {
    if ($mode -eq "2") {
      New-Item -ItemType Directory -Path $targetDir | Out-Null
      Write-Log "Création dossier : $targetDir"
    } else {
      Write-Log "AUDIT - Dossier à créer : $targetDir" "INFO"
    }
  }

  # Déplacer le fichier
  $destPath = Join-Path $targetDir $f.Name

  if ($mode -eq "2") {
    Move-Item -Path $f.FullName -Destination $destPath
    Add-Content -Path $reportPath -Value ("DEPLACE : {0} -> {1}" -f $f.Name, $ext)
    Write-Log "Déplacement : $($f.Name) -> $ext"
  } else {
    Add-Content -Path $reportPath -Value ("AUDIT : {0} -> {1}" -f $f.Name, $ext)
    Write-Log "AUDIT - Déplacement prévu : $($f.Name) -> $ext"
  }
}

Write-Log "Fin du script"
Write-Output "Rapport : $reportPath"
Write-Output "Log    : $logPath"

Explication des étapes

  • Read-Host : entrée utilisateur (dossier + mode)
  • Test-Path : contrôle existence avant traitement
  • Out-File : crée un rapport (écrasé à chaque exécution)
  • Add-Content : log + ajout progressif au rapport
  • Get-ChildItem -File : récupère uniquement les fichiers
  • foreach : traitement de masse
  • New-Item : création du dossier extension en mode action
  • Move-Item : déplacement réel en mode action
Conseil : commencez toujours par Mode 1 (Audit), vérifiez le rapport, puis lancez Mode 2 (Action).
Exercices

3 exercices guidés

Corrigés masqués. Cherchez avant d’ouvrir.

Exercice 1 — Ajouter un mode 3 “WhatIf”

Ajoutez un mode 3 : le script doit exécuter Move-Item avec -WhatIf (simulation PowerShell), en plus du rapport.

Corrigé (piste)
# Ajouter dans le contrôle :
# if ($mode -notin "1","2","3") { ... }

# Dans le déplacement :
# Move-Item -Path $f.FullName -Destination $destPath -WhatIf

Exercice 2 — Exclure certains fichiers

Modifiez le script pour ignorer report.txt et script.log afin qu’ils ne soient pas déplacés.

Corrigé
$files = Get-ChildItem -Path $sourceDir -File |
  Where-Object { $_.Name -notin @("report.txt","script.log") }

Exercice 3 — Dossier “SANS_EXTENSION”

Créez un comportement : si un fichier n’a pas d’extension, il doit aller dans un dossier nommé SANS_EXTENSION. (Assurez-vous que c’est bien le cas.)

Corrigé (extrait)
$ext = $f.Extension
if ([string]::IsNullOrWhiteSpace($ext)) { $ext = "SANS_EXTENSION" }
else { $ext = $ext.TrimStart(".").ToUpper() }
© 2026 — JcMamiah · PowerShell (TSSR)