4. Script prêt à planifier
- Transformer un script interactif (Read-Host) en script paramétrable
- Exécuter sans interaction (ligne de commande / planification)
- Produire une sortie exploitable : rapport + logs
- Connaître les points clés du Planificateur Windows
Pourquoi paramétrer un script ?
Un script planifié doit pouvoir s’exécuter sans écran, sans intervention, et sans question à l’utilisateur.
On remplace donc Read-Host par des paramètres (bloc param(...)).
Paramètres
- param() définir les entrées du script
- [ValidateSet] limiter les valeurs possibles
- [Parameter(Mandatory)] rendre obligatoire
Robustesse
- Test-Path contrôler les chemins
- Try/Catch capturer les erreurs
- -ErrorAction Stop forcer l’erreur “catchable”
Traçabilité
- Add-Content log en append
- Out-File rapport (écrase)
- Get-Date horodatage
Exemple : organisation par extension (version paramétrée)
Objectif : reprendre la logique du chapitre 3, mais sans Read-Host, avec paramètres et gestion d’erreurs.
param(
[Parameter(Mandatory=$true)]
[string]$SourceDir,
[ValidateSet("Audit","Action")]
[string]$Mode = "Audit"
)
# =========================
# Contrôles
# =========================
if (-not (Test-Path $SourceDir)) {
Write-Output "Dossier introuvable : $SourceDir"
exit 1
}
# =========================
# 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 - Mode=$Mode - Source=$SourceDir"
# =========================
# Traitement avec gestion d’erreurs
# =========================
try {
$files = Get-ChildItem -Path $SourceDir -File |
Where-Object { $_.Name -notin @("report.txt","script.log") }
foreach ($f in $files) {
$ext = $f.Extension
if ([string]::IsNullOrWhiteSpace($ext)) { $ext = "SANS_EXTENSION" }
else { $ext = $ext.TrimStart(".").ToUpper() }
$targetDir = Join-Path $SourceDir $ext
if (-not (Test-Path $targetDir)) {
if ($Mode -eq "Action") {
New-Item -ItemType Directory -Path $targetDir -ErrorAction Stop | Out-Null
Write-Log "Création dossier : $targetDir"
} else {
Write-Log "AUDIT - Dossier à créer : $targetDir"
}
}
$destPath = Join-Path $targetDir $f.Name
if ($Mode -eq "Action") {
Move-Item -Path $f.FullName -Destination $destPath -ErrorAction Stop
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 - OK"
Write-Output "OK - Rapport : $reportPath"
exit 0
}
catch {
Write-Log "Erreur : $($_.Exception.Message)" "ERROR"
Write-Output "ERREUR : $($_.Exception.Message)"
exit 2
}
Explication des éléments importants
- param(...) : définit les entrées du script
- [Parameter(Mandatory)] : empêche l’exécution sans source
- [ValidateSet] : limite le mode à Audit/Action
- exit 0/1/2 : codes retour (utile en exploitation / supervision)
- Try/Catch : capture les erreurs du traitement
- -ErrorAction Stop : force l’erreur à déclencher le catch
- Write-Log : trace toutes les étapes
Exécuter sans interaction (CLI)
# Mode Audit
powershell.exe -ExecutionPolicy Bypass -File .\organize.ps1 -SourceDir "C:\Temp\source" -Mode Audit
# Mode Action
powershell.exe -ExecutionPolicy Bypass -File .\organize.ps1 -SourceDir "C:\Temp\source" -Mode Action
-ExecutionPolicy Bypass est souvent utilisé en planification.
En entreprise, on privilégie une politique maîtrisée + scripts signés, mais cela dépasse ce module.
Configurer une tâche planifiée (Task Scheduler)
Exemple : exécuter chaque jour à 08:00 un script de rangement en mode audit.
Paramètres recommandés
- Nom : PS_Organize_Audit
- Déclencheur : quotidien 08:00
- Action : démarrer un programme
- Option : “Exécuter même si l’utilisateur n’est pas connecté” (si besoin)
Action (command line)
Programme/script :
powershell.exe
Ajouter des arguments :
-ExecutionPolicy Bypass -File "C:\Scripts\organize.ps1" -SourceDir "C:\Temp\source" -Mode Audit
Démarrer dans :
C:\Scripts
Bonnes pratiques
- Logs dans un dossier accessible au compte exécutant
- Éviter les chemins relatifs si “Démarrer dans” n’est pas défini
- Tester en ligne de commande avant d’activer la tâche
Planifier l’exécution d’un script avec le Planificateur de tâches (Windows)
Ce guide vous explique comment créer une tâche planifiée pour exécuter un script PowerShell sans interaction, de manière fiable et traçable.
- Un script
.ps1testé en ligne de commande (ex.organize.ps1) - Un chemin fixe vers le script (ex.
C:\Scripts\organize.ps1) - Un dossier cible sur lequel le compte exécutant a les droits (lecture/écriture)
Étape 1 — Tester la commande manuellement
Avant toute planification, validez que la commande fonctionne dans un terminal PowerShell.
powershell.exe -ExecutionPolicy Bypass -File "C:\Scripts\organize.ps1" -SourceDir "C:\Temp\source" -Mode Audit
Étape 2 — Ouvrir le Planificateur de tâches
- Menu Démarrer → recherchez Planificateur de tâches (Task Scheduler)
- Ouvrez l’outil (idéalement en administrateur si nécessaire)
Étape 3 — Créer une tâche (recommandé)
- Dans le volet droit : cliquez sur Créer une tâche… (plutôt que « Créer une tâche de base »)
- Onglet Général :
- Nom : ex.
PS_Organize_Audit - Exécuter que l’utilisateur soit connecté ou non (si besoin)
- Exécuter avec les autorisations maximales (si votre script nécessite des droits élevés)
- Nom : ex.
Étape 4 — Déclencheur (quand exécuter ?)
- Onglet Déclencheurs → Nouveau…
- Choisissez : Quotidien / Hebdomadaire / Au démarrage selon le besoin
- Définissez l’heure (ex. 08:00) puis validez
Étape 5 — Action (comment exécuter ?)
L’action doit lancer powershell.exe avec les bons arguments.
Programme/script
powershell.exe
Astuce : utilisez le chemin complet si nécessaire (ex. C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe).
Ajouter des arguments
-ExecutionPolicy Bypass -NoProfile -File "C:\Scripts\organize.ps1" -SourceDir "C:\Temp\source" -Mode Audit
-NoProfile évite que le profil utilisateur n’influence l’exécution (plus stable en exploitation).
Démarrer dans (très important)
C:\Scripts
Indispensable si votre script utilise des chemins relatifs (ex. .\ressources\...).
Étape 6 — Conditions & paramètres
- Onglet Conditions : désactivez les contraintes inutiles (ex. « uniquement sur secteur ») si ce n’est pas votre cas.
- Onglet Paramètres : cochez « Exécuter la tâche dès que possible après un démarrage manqué » (utile).
Étape 7 — Tester la tâche
- Sélectionnez la tâche dans la bibliothèque
- Cliquez sur Exécuter
- Vérifiez :
- le code de résultat (colonne « Résultat de la dernière exécution »)
- les fichiers report.txt et script.log
Étape 8 — Diagnostic en cas d’échec (réflexes TSSR)
- Vérifiez les droits du compte exécutant sur
$SourceDir(lecture/écriture). - Vérifiez les guillemets : les chemins contenant des espaces doivent être entre
" ". - Activez l’Historique de la tâche pour voir les événements (bibliothèque → clic droit → Historique).
- Ajoutez des logs dans le script (déjà conseillé) et consultez
script.log.
- Tester en Mode Audit avant Mode Action
- Utiliser
-NoProfileet un chemin complet vers le script - Centraliser les logs dans un dossier dédié si plusieurs tâches existent
Exercices guidés (planification)
Corrigés masqués. Cherchez avant d’ouvrir.
Exercice 1 — Ajouter un paramètre LogDir
Ajoutez un paramètre -LogDir optionnel.
Si fourni, le log doit être écrit dans ce dossier, sinon dans $SourceDir.
Corrigé (piste)
param(
[Parameter(Mandatory=$true)][string]$SourceDir,
[ValidateSet("Audit","Action")][string]$Mode="Audit",
[string]$LogDir
)
if ($LogDir) {
if (-not (Test-Path $LogDir)) { New-Item -ItemType Directory -Path $LogDir | Out-Null }
$logPath = Join-Path $LogDir "script.log"
} else {
$logPath = Join-Path $SourceDir "script.log"
}
Exercice 2 — Ajouter un code retour spécifique
Si le dossier est vide (aucun fichier à traiter), retourner exit 3
et écrire un message dans le log.
Corrigé
if ($files.Count -eq 0) {
Write-Log "Aucun fichier à traiter" "WARN"
exit 3
}
Exercice 3 — Planificateur : argumentation
Dans le Planificateur, expliquez pourquoi “Démarrer dans” est important si vous utilisez des chemins relatifs.
Réponse attendue
Parce que la tâche planifiée n'exécute pas forcément le script depuis son dossier.
Sans "Démarrer dans", un chemin relatif .\ressources\... peut pointer vers un autre dossier
et provoquer un "fichier introuvable".