Exercices scripts PowerShell

1. Inventaire rapide des services « critiques »

Contexte. Vous devez produire un état des services critiques (ex. WinRM, Dnscache, DHCP, Spooler).
Tâches.

  • Déclarez une variable $servicesCritiques (tableau de noms).
  • Utilisez un pipeline Get-Service ... | Select-Object ... | Sort-Object ....
  • Affichez un résumé formaté (Nom, Statut, Type de démarrage) en ordre alphabétique.
  • Si un service est arrêté, affichez un message et proposez à l'utilisateur de le démarrer.

Matière couverte par cet exercice : variables, tableaux, pipeline, sélection d'objets, tri, if/else.

Piste
$servicesCritiques = @('WinRM','Spooler','Dnscache','Dhcp')
Get-Service -Name $servicesCritiques | Select Name, Status, StartType | Sort-Object Name
Réponse
# Inventaire rapide des services critiques

# Tableau des services critiques
$servicesCritiques = @('WinRM','Spooler','Dnscache','Dhcp')

# Pipeline : obtenir les services et trier par nom
$inventaire = Get-Service -Name $servicesCritiques |
              Select-Object Name, Status, StartType |
              Sort-Object Name

# Affichage de l'inventaire
$inventaire

# Vérifier si un service est arrêté et afficher un message
foreach ($svc in $inventaire) {
    if ($svc.Status -eq 'Stopped') {
        $reponse = Read-Host "Le service $($svc.Name) est arrêté. Voulez-vous le démarrer ? (o/n)"
        if ($reponse -eq 'o' or $reponse -eq 'O') {
            Start-Service -Name $svc.Name
            Write-Output "Démarré : $($svc.Name)"
        }
        elseif ($reponse -eq 'n' or $reponse -eq 'N') {
            Write-Output "Laissé arrêté : $($svc.Name)"
        }
        else {
            Write-Output "Réponse non reconnue. Aucune action pour : $($svc.Name)"
        }
    }
}

2.Rapport d’espace disque minimaliste

Contexte. Vous devez vérifier si un lecteur descend sous un seuil (en % libre).
Tâches.

  • Créez un script avec paramètres: -DriveLetter, -ThresholdPercent.
  • Récupérez la taille/volume libre (WMI/CIM) avec la commande Get-CimInstance Win32_LogicalDisk.
  • Utilisez if/elseif/else pour catégoriser : OK / Avertissement / Critique.
  • Affichez une ligne par lecteur (boucle foreach sur un tableau de lettres).
Piste
param(
    [string[]]$DriveLetter = @('C'), 
    [int]$ThresholdPercent = 15)
foreach($drive in $DriveLetter){
  $vol = Get-CimInstance Win32_LogicalDisk -Filter "DeviceID='${drive}:'"
}
Réponse
param(
    [string[]]$DriveLetter = @('C'), 
    [int]$ThresholdPercent = 15
)

foreach ($drive in $DriveLetter) {
    # Récupérer les infos du lecteur
    $vol = Get-CimInstance Win32_LogicalDisk -Filter "DeviceID='${drive}:'"

    # Calcul du pourcentage libre
    $perc_libre = ($vol.FreeSpace / $vol.Size) * 100

    # Vérification des seuils
    if ($perc_libre -lt $ThresholdPercent) {
        Write-Host "${drive}: Critique (Pourcentage libre: $perc_libre)"
    }
    elseif ($perc_libre -eq $ThresholdPercent) {
        Write-Host "${drive}: Avertissement (Pourcentage libre: $perc_libre)"
    }
    else {
        Write-Host "${drive}: OK (Pourcentage libre: $perc_libre)"
    }
}

Exemple d'utilisation:

.\Check-Drives.ps1 -DriveLetter "C","D" -ThresholdPercent 15

3. Ping de santé avec seuil de latence

Contexte. Vous devez tester des serveurs et alerter si la latence moyenne > seuil.
Tâches.

  • Préparez un fichier servers.txt (une machine par ligne).
  • Lisez le fichier avec Get-Content et utilisez ForEach-Object avec Test-Connection -Count 4 pour chaque serveur.
  • Calculez la moyenne (objets) avec Measure-Object.
  • Affichez à l'écran chaque serveur et sa latence moyenne (format CSV simple, séparé par des virgules).
  • Si moyenne > seuil → affichez un message d’alerte.

Pour tester ce script sur votre machine virtuelle locale, créez un fichier servers.txt avec le contenu suivant :

localhost
192.168.1.1 (ou l'adresse IP de votre routeur obtenue via ipconfig)
google.com
Piste
Get-Content .\servers.txt | ForEach-Object {
  $results = Test-Connection $_ -Count 4 -ErrorAction SilentlyContinue
  $moyenne = ($results | Measure-Object -Property ResponseTime -Average).Average
}
Réponse
param(
    [int] $ThresholdMs = 100
)

# Lire la liste des serveurs depuis le fichier
Get-Content .\servers.txt | ForEach-Object {

    # Test de connectivité (4 pings)
    $results = Test-Connection -ComputerName $_ -Count 4 -ErrorAction SilentlyContinue

    # Calcul de la moyenne
    $moyenne = ($results | Measure-Object -Property ResponseTime -Average).Average

    # Ligne CSV simple : Serveur, Moyenne
    $ligne = "$_, $moyenne"
    Write-Output $ligne

    # Vérifier le seuil
    if ($moyenne -gt $ThresholdMs) {
        Write-Host "ALERTE : $_ latence moyenne $moyenne ms (> $ThresholdMs ms)" -ForegroundColor Red
    }
}

4. Vérification de ports réseau à partir d’une liste

Contexte. Vous recevez un fichier endpoints.txt avec lignes host:port.
Tâches.

  • Lisez le fichier avec Get-Content, et faites un foreach-object pour séparer host/port (manipulation string).
  • Testez le port (Test-NetConnection ou TcpClient).
  • Utilisez if/elseif/else pour classer: Ouvert, Fermé, Host down.
  • Exportez un rapport CSV.

Pour tester ce script sur votre machine virtuelle locale, créez un fichier endpoints.txt avec le contenu suivant :

localhost:80
localhost:443
localhost:9999
google.com:80
invalid.hostname:80
Piste
Get-Content .\endpoints.txt | ForEach-Object {
  $parts = $_ -split ':'
  $hote,$port = $parts[0], [int]$parts[1]
  # Test-NetConnection $host -Port $port
}
Réponse
param(
    [int]    $DefaultTimeoutMs = 2000
)

# Collecte des résultats
$rows = @()
$rows += "Host,Port,Status,LatencyMs"   # en-tête manuelle

# Lecture du fichier et traitement par ForEach-Object
Get-Content .\endpoints.txt | ForEach-Object {
    # Séparer host:port (manipulation de chaîne)
      $parts = $_ -split ':'
      $hote,$port = $parts[0], [int]$parts[1]


    # Test du port
    $t = Test-NetConnection -ComputerName $hote -Port $port -ErrorAction SilentlyContinue -WarningAction SilentlyContinue

    # Classification
    if ($t.TcpTestSucceeded) {
        $status = "Ouvert"
    }
    elseif (-not $t.PingSucceeded) {
        $status = "Host down"
    }
    else {
        $status = "Fermé"
    }

    # Objet de sortie (pour CSV)
    $rows += "$hote,$port,$status,$($t.PingReplyDetails.RoundtripTime)"

}

# Export CSV
# Sauvegarde
$rows | Set-Content ".\ports_report.csv"

Write-Host "Rapport exporté : .\ports_report.csv"