Polarys
PowerShell pour l'administration/Automatisation et scripts

Automatisation et scripts

Fonctions et gestion des erreurs

Fonctions et gestion des erreurs

Un bon script PowerShell est réutilisable et robuste. Les fonctions encapsulent la logique, la gestion des erreurs empêche les crashs silencieux.

Définir une fonction

function Get-DiskReport {
    param(
        [Parameter(Mandatory)]
        [string]$ComputerName,

        [int]$SeuilAlerte = 20  # valeur par défaut
    )

    $disques = Get-WmiObject -Class Win32_LogicalDisk -ComputerName $ComputerName -Filter "DriveType=3"

    foreach ($disque in $disques) {
        $librePct = [math]::Round(($disque.FreeSpace / $disque.Size) * 100, 1)
        [PSCustomObject]@{
            Serveur    = $ComputerName
            Lettre     = $disque.DeviceID
            Total_GB   = [math]::Round($disque.Size / 1GB, 1)
            Libre_GB   = [math]::Round($disque.FreeSpace / 1GB, 1)
            Libre_Pct  = $librePct
            Alerte     = $librePct -lt $SeuilAlerte
        }
    }
}

# Utilisation
Get-DiskReport -ComputerName "SRV-FILE01"
Get-DiskReport -ComputerName "SRV-WEB01" -SeuilAlerte 10

Gestion des erreurs avec try/catch

function Test-ServiceCritique {
    param([string]$Nom, [string]$Serveur = $env:COMPUTERNAME)

    try {
        $service = Get-Service -Name $Nom -ComputerName $Serveur -ErrorAction Stop
        if ($service.Status -ne 'Running') {
            Write-Warning "$Nom est arrêté sur $Serveur : tentative de démarrage..."
            Start-Service -InputObject $service -ErrorAction Stop
            Write-Host "$Nom démarré avec succès." -ForegroundColor Green
        } else {
            Write-Host "$Nom est actif sur $Serveur." -ForegroundColor Green
        }
    } catch [Microsoft.PowerShell.Commands.ServiceCommandException] {
        Write-Error "Service $Nom introuvable sur $Serveur : $_"
    } catch {
        Write-Error "Erreur inattendue sur $Serveur/$Nom : $_"
    }
}

Paramètres avancés

function Send-AlertEmail {
    [CmdletBinding(SupportsShouldProcess)]
    param(
        [Parameter(Mandatory, ValueFromPipeline)]
        [string]$Message,

        [ValidateSet('Info', 'Warning', 'Critical')]
        [string]$Niveau = 'Info'
    )

    process {
        if ($PSCmdlet.ShouldProcess("Envoi email : $Message")) {
            Write-Host "[$Niveau] $Message"
            # Logique d'envoi réel ici
        }
    }
}

# -WhatIf fonctionne automatiquement grâce à SupportsShouldProcess
"Disque plein" | Send-AlertEmail -Niveau Critical -WhatIf

Cas concret : script de surveillance complet

$serveurs = @("SRV-DC01", "SRV-FILE01", "SRV-WEB01")
$erreurs = @()

foreach ($srv in $serveurs) {
    try {
        $rapport = Get-DiskReport -ComputerName $srv -ErrorAction Stop
        $alertes = $rapport | Where-Object { $_.Alerte -eq $true }
        if ($alertes) {
            $erreurs += $alertes
            Write-Warning "Espace faible sur $srv"
        }
    } catch {
        Write-Error "Impossible de joindre $srv : $_"
        $erreurs += [PSCustomObject]@{ Serveur = $srv; Lettre = 'N/A'; Alerte = $true }
    }
}

if ($erreurs.Count -gt 0) {
    $erreurs | Export-Csv -Path C:\Alertes\disques-$(Get-Date -Format 'yyyyMMdd').csv -NoTypeInformation
    Write-Host "$($erreurs.Count) alerte(s) exportée(s)." -ForegroundColor Red
}

Erreurs fréquentes

  • -ErrorAction Stop oublié dans try/catch : sans ce paramètre, les erreurs non-terminantes (cmdlets standard) ne sont pas capturées par catch.
  • catch trop large : un seul catch { } cache tous les types d'erreur. Préférez des blocs catch [TypeException] spécifiques d'abord.
  • Fonctions sans param() : sans bloc param, pas de validation automatique, pas de Mandatory, pas de pipeline.

À retenir

  • function Nom { param([Parameter(Mandatory)][string]$P) ... } → structure de base.
  • try { } catch { } + -ErrorAction Stop → capturer les erreurs cmdlet.
  • [CmdletBinding(SupportsShouldProcess)] → activer -WhatIf automatiquement.
  • Tester toujours avec -WhatIf avant d'exécuter un script destructif en production.

Quiz de validation

Quiz - 2 questions

1. Pourquoi faut-il ajouter -ErrorAction Stop dans un bloc try/catch ?

2. Quel attribut ajouter à un param() pour qu'il soit obligatoire ?

Suis ta progression

Crée un compte gratuit pour suivre ta progression et accéder à toutes les leçons.