TP N°5 : Script de création d'utilisateurs en masse (import CSV)

Sophie pose enfin le ticket qui a servi de déclencheur à toute cette formation, évoqué dès l’introduction : “200 comptes à créer pour la rentrée, chacun avec un nom, un prénom et un service. Cette fois, je veux un script solide : s’il y a un souci sur un compte, il ne doit pas bloquer les 199 autres.”

Objectif

Combiner fonctions (5.4), structures de contrôle (5.3) et gestion d’erreurs (5.5) pour construire un script robuste de création de comptes locaux à partir d’un fichier CSV, sans qu’un échec isolé n’interrompe le traitement des autres lignes.

Préparation : le fichier CSV

Créez un fichier comptes.csv avec ce contenu :

Nom,Prenom,Service
Dupont,Julie,Comptabilite
Martin,Paul,Informatique
Durand,Sophie,RH

Consignes

Étape 1 — Importez le fichier CSV dans une variable, avec Import-Csv.
Indice : Import-Csv renvoie directement un tableau d’objets, une ligne CSV = un objet, chaque colonne = une propriété — pas besoin de découper du texte manuellement.

Étape 2 — Écrivez une fonction New-CompteDepuisCSV qui prend en paramètres Nom, Prenom et Service, et qui construit un identifiant de connexion au format p.dupont (première lettre du prénom, point, nom, en minuscules).
Indice : .ToLower() et .Substring(0,1) permettent respectivement de passer en minuscules et de récupérer la première lettre d’une chaîne.

Étape 3 — Dans cette fonction, utilisez try/catch avec -ErrorAction Stop pour tenter la création du compte avec New-LocalUser, sans mot de passe interactif cette fois (générez-en un aléatoire simple pour ce TP).

Étape 4 — Si la création échoue (compte déjà existant, par exemple), affichez un Write-Warning clair, et continuez le traitement des autres comptes.

Étape 5 — Parcourez le CSV importé avec une boucle, en appelant la fonction pour chaque ligne. À la fin, affichez un résumé : nombre de comptes créés avec succès, nombre d’échecs.

Voir la solutionMasquer la solution
function New-CompteDepuisCSV {
    param (
        [Parameter(Mandatory = $true)]
        [string]$Nom,

        [Parameter(Mandatory = $true)]
        [string]$Prenom,

        [Parameter(Mandatory = $true)]
        [string]$Service
    )

    $identifiant = "$($Prenom.Substring(0,1))." + $Nom.ToLower()
    $motDePasseTemp = ConvertTo-SecureString "Nordika2026!" -AsPlainText -Force

    try {
        New-LocalUser -Name $identifiant `
                       -Password $motDePasseTemp `
                       -FullName "$Prenom $Nom" `
                       -Description "Service : $Service" `
                       -ErrorAction Stop

        return [PSCustomObject]@{
            Identifiant = $identifiant
            Statut      = "Créé"
            Erreur      = $null
        }
    } catch {
        Write-Warning "Échec pour $identifiant : $($_.Exception.Message)"
        return [PSCustomObject]@{
            Identifiant = $identifiant
            Statut      = "Échec"
            Erreur      = $_.Exception.Message
        }
    }
}

# Étape 1 : import
$comptes = Import-Csv -Path ".\comptes.csv"

# Étape 5 : traitement en boucle
$resultats = foreach ($ligne in $comptes) {
    New-CompteDepuisCSV -Nom $ligne.Nom -Prenom $ligne.Prenom -Service $ligne.Service
}

# Résumé final
$succes = ($resultats | Where-Object { $_.Statut -eq "Créé" }).Count
$echecs = ($resultats | Where-Object { $_.Statut -eq "Échec" }).Count

Write-Output "`nRésumé : $succes compte(s) créé(s), $echecs échec(s)"
$resultats | Format-Table -AutoSize

Points clés à retenir :

  • $resultats = foreach (...) { } : la même astuce vue au TP de la section 4, chaque valeur renvoyée par la fonction (via return) est collectée automatiquement dans le tableau $resultats.
  • -ErrorAction Stop sur New-LocalUser est indispensable : sans lui, une erreur (compte déjà existant, par exemple) serait non-terminante, et le catch ne se déclencherait jamais — exactement le piège détaillé en leçon 5.5.
  • Le mot de passe est ici volontairement simplifié pour l’exercice ("Nordika2026!" en dur) — en production, on générerait un mot de passe aléatoire par compte, et on ne l’afficherait jamais en clair dans le script lui-même. On abordera une gestion plus rigoureuse des secrets en section 9.
  • Le script continue bien pour les 200 lignes même si l’une d’elles échoue : c’est précisément l’exigence de Sophie dans l’énoncé.

Retour d’expérience terrain : ce type de script — import CSV, boucle, gestion d’erreur individuelle, résumé final — est probablement le squelette le plus réutilisé dans l’administration système au quotidien, bien au-delà de la création de comptes : migration de données, vérification de masse, nettoyage de fichiers. Une fois ce schéma compris, vous pourrez l’adapter à la quasi-totalité des tickets répétitifs qui atterriront sur votre bureau.