Automatisation PowerShell pour les administrateurs système en 2026 : 10 scripts que vous utiliserez quotidiennement

Automatisation PowerShell pour les administrateurs système en 2026 : 10 scripts que vous utiliserez quotidiennement

Introduction : Pourquoi PowerShell est incontournable pour les administrateurs système en 2026

En 2026, PowerShell n'est plus un simple interpréteur de commandes : c'est le système nerveux central de l'administration Windows. Avec PowerShell 7.x fonctionnant sur toutes les plateformes (Windows, Linux et macOS) et son intégration poussée avec Active Directory, Azure, Microsoft 365 et des centaines de systèmes tiers, tout administrateur système qui ne maîtrise pas PowerShell se prive d'énormes gains d'efficacité.

Cet article vous propose 10 scripts PowerShell prêts à l'emploi qui couvrent les tâches essentielles des administrateurs système : inventaire, surveillance, gestion des utilisateurs, sauvegardes, audits de sécurité, etc. Chaque script est complet, fonctionnel et éprouvé.

Tous les scripts nécessitent PowerShell 7.x (multiplateforme, activement maintenu). Téléchargez-le ici : https://github.com/PowerShell/PowerShell/releases

Certains scripts nécessitent le module ActiveDirectory (installez RSAT sur Windows ou le module depuis PowerShell Gallery à l' adresse https://www.powershellgallery.com ).

Script 1 : Inventaire complet des machines du réseau

Description

Analyse votre réseau et collecte des informations détaillées sur le matériel et les logiciels de toutes les machines Windows accessibles. Effectue d'abord une analyse ping, puis utilise WMI pour un inventaire complet. Exporte les résultats au format CSV pour la génération de rapports.

# Script 1: Network Inventory
# Requires: PowerShell 7.x, WinRM enabled on targets
# Usage: .Inventory-Network.ps1 -Subnet "192.168.1" -OutputPath "C:Reportsinventory.csv"

param(
    [string]$Subnet = "192.168.1",
    [string]$OutputPath = ".network-inventory.csv"
)

$results = [System.Collections.Generic.List[PSObject]]::new()

# Ping sweep to find live hosts
Write-Host "[*] Scanning subnet $Subnet.0/24..." -ForegroundColor Cyan
$liveHosts = 1..254 | ForEach-Object -Parallel {
    $ip = "$using:Subnet.$_"
    if (Test-Connection -ComputerName $ip -Count 1 -TimeoutSeconds 1 -Quiet) {
        $ip
    }
} -ThrottleLimit 50

Write-Host "[+] Found $($liveHosts.Count) live hosts" -ForegroundColor Green

foreach ($ip in $liveHosts) {
    try {
        $hostname = [System.Net.Dns]::GetHostEntry($ip).HostName
    } catch { $hostname = "N/A" }

    try {
        $cs = Get-WmiObject -Class Win32_ComputerSystem -ComputerName $ip -ErrorAction Stop
        $os = Get-WmiObject -Class Win32_OperatingSystem -ComputerName $ip -ErrorAction Stop
        $cpu = Get-WmiObject -Class Win32_Processor -ComputerName $ip | Select-Object -First 1
        $disk = Get-WmiObject -Class Win32_LogicalDisk -ComputerName $ip -Filter "DriveType=3" | Select-Object -First 1

        $results.Add([PSCustomObject]@{
            IP           = $ip
            Hostname     = $hostname
            Manufacturer = $cs.Manufacturer
            Model        = $cs.Model
            RAM_GB       = [math]::Round($cs.TotalPhysicalMemory / 1GB, 1)
            CPU          = $cpu.Name
            OS           = $os.Caption
            OSVersion    = $os.Version
            DiskFree_GB  = [math]::Round($disk.FreeSpace / 1GB, 1)
            DiskTotal_GB = [math]::Round($disk.Size / 1GB, 1)
            LastBoot     = $os.ConvertToDateTime($os.LastBootUpTime)
        })
        Write-Host "[+] $ip ($hostname) - OK" -ForegroundColor Green
    } catch {
        $results.Add([PSCustomObject]@{
            IP = $ip; Hostname = $hostname; Manufacturer = "UNREACHABLE"
            Model = ""; RAM_GB = 0; CPU = ""; OS = ""; OSVersion = ""
            DiskFree_GB = 0; DiskTotal_GB = 0; LastBoot = $null
        })
        Write-Host "[-] $ip - WMI failed: $_" -ForegroundColor Yellow
    }
}

$results | Export-Csv -Path $OutputPath -NoTypeInformation -Encoding UTF8
Write-Host "`n[✓] Inventory saved to: $OutputPath" -ForegroundColor Green
Write-Host "[✓] Total machines: $($results.Count)" -ForegroundColor Green

Script 2 : Rapport des utilisateurs inactifs d’AD (plus de 30 jours)

Description

Trouve tous les comptes utilisateurs Active Directory inactifs depuis 30 jours ou plus. Génère un rapport détaillé et permet, en option, de désactiver les comptes. Indispensable pour la conformité de sécurité et la gestion des licences.

# Script 2: AD Inactive Users Report
# Requires: ActiveDirectory module (RSAT)
# Usage: .Get-InactiveUsers.ps1 -DaysInactive 30 -Disable $false -OutputPath "C:Reportsinactive-users.csv"

param(
    [int]$DaysInactive = 30,
    [bool]$Disable = $false,
    [string]$OutputPath = ".inactive-users.csv"
)

Import-Module ActiveDirectory

$cutoffDate = (Get-Date).AddDays(-$DaysInactive)
Write-Host "[*] Finding users inactive since: $cutoffDate" -ForegroundColor Cyan

$inactiveUsers = Get-ADUser -Filter {
    Enabled -eq $true -and LastLogonDate -lt $cutoffDate
} -Properties LastLogonDate, Department, Manager, EmailAddress, Description, Created |
Where-Object { $_.LastLogonDate -ne $null } |
Sort-Object LastLogonDate

$report = $inactiveUsers | ForEach-Object {
    $manager = if ($_.Manager) {
        (Get-ADUser $_.Manager -Properties DisplayName).DisplayName
    } else { "N/A" }

    [PSCustomObject]@{
        SamAccountName  = $_.SamAccountName
        DisplayName     = $_.Name
        Email           = $_.EmailAddress
        Department      = $_.Department
        Manager         = $manager
        LastLogonDate   = $_.LastLogonDate
        DaysInactive    = [math]::Round(((Get-Date) - $_.LastLogonDate).TotalDays)
        AccountCreated  = $_.Created
        Description     = $_.Description
    }
}

$report | Export-Csv -Path $OutputPath -NoTypeInformation -Encoding UTF8

Write-Host "[+] Found $($inactiveUsers.Count) inactive users" -ForegroundColor Yellow
Write-Host "[✓] Report exported to: $OutputPath" -ForegroundColor Green

if ($Disable) {
    $inactiveUsers | Disable-ADAccount
    Write-Host "[!] All inactive accounts have been DISABLED" -ForegroundColor Red
}

# Summary by department
Write-Host "`n[*] Top departments with inactive users:" -ForegroundColor Cyan
$report | Group-Object Department | Sort-Object Count -Descending | Select-Object -First 10 |
    Format-Table Name, Count -AutoSize

Script 3 : Surveillance de l’espace disque avec alerte par e-mail

Description

Surveille l'espace disque sur plusieurs serveurs et envoie une alerte par e-mail lorsqu'un disque passe sous un seuil configurable. Idéal pour une exécution planifiée toutes les heures.

# Script 3: Disk Space Monitor with Email Alert
# Requires: PowerShell 7.x, SMTP access
# Usage: .Monitor-DiskSpace.ps1 -Servers @("srv01","srv02") -ThresholdGB 20

param(
    [string[]]$Servers = @("localhost"),
    [int]$ThresholdGB = 20,
    [string]$SmtpServer = "smtp.company.com",
    [string]$From = "monitoring@company.com",
    [string]$To = "sysadmin@company.com"
)

$alerts = [System.Collections.Generic.List[PSObject]]::new()
$report = [System.Collections.Generic.List[PSObject]]::new()

foreach ($server in $Servers) {
    try {
        $disks = Get-WmiObject Win32_LogicalDisk -ComputerName $server -Filter "DriveType=3" -ErrorAction Stop

        foreach ($disk in $disks) {
            $freeGB = [math]::Round($disk.FreeSpace / 1GB, 2)
            $totalGB = [math]::Round($disk.Size / 1GB, 2)
            $usedPct = [math]::Round((($disk.Size - $disk.FreeSpace) / $disk.Size) * 100, 1)

            $entry = [PSCustomObject]@{
                Server    = $server
                Drive     = $disk.DeviceID
                TotalGB   = $totalGB
                FreeGB    = $freeGB
                UsedPct   = $usedPct
                Status    = if ($freeGB -lt $ThresholdGB) { "CRITICAL" } else { "OK" }
            }
            $report.Add($entry)

            if ($freeGB -lt $ThresholdGB) {
                $alerts.Add($entry)
                Write-Host "[ALERT] $server $($disk.DeviceID) - $freeGB GB free ($usedPct% used)" -ForegroundColor Red
            } else {
                Write-Host "[OK] $server $($disk.DeviceID) - $freeGB GB free ($usedPct% used)" -ForegroundColor Green
            }
        }
    } catch {
        Write-Host "[ERROR] Cannot reach $server`: $_" -ForegroundColor Yellow
    }
}

if ($alerts.Count -gt 0) {
    $body = $alerts | ConvertTo-Html -Title "Disk Space Alerts" |
        Out-String

    Send-MailMessage -SmtpServer $SmtpServer -From $From -To $To `
        -Subject "⚠️ DISK SPACE ALERT - $($alerts.Count) drives critical" `
        -Body $body -BodyAsHtml -Priority High

    Write-Host "`n[!] Alert email sent for $($alerts.Count) critical drives" -ForegroundColor Red
}

$report | Format-Table -AutoSize

Script 4 : Sauvegarde automatisée de fichiers avec compression ZIP

Description

Crée des sauvegardes ZIP horodatées des dossiers spécifiés, avec rotation pour ne conserver que les N dernières sauvegardes. Aucun outil tiers requis : utilise la compression native .NET.

# Script 4: Automated Backup with ZIP Compression
# Requires: PowerShell 5.1+ or 7.x
# Usage: .Backup-Files.ps1 -Source "C:Data" -Dest "D:Backups" -KeepLast 7

param(
    [string]$Source = "C:Data",
    [string]$Destination = "D:Backups",
    [int]$KeepLast = 7,
    [string]$LogFile = "D:Backupsbackup.log"
)

function Write-Log {
    param([string]$Message)
    $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
    "$timestamp - $Message" | Tee-Object -FilePath $LogFile -Append
}

# Create destination if it doesn't exist
if (-not (Test-Path $Destination)) {
    New-Item -ItemType Directory -Path $Destination -Force | Out-Null
}

$timestamp = Get-Date -Format "yyyyMMdd_HHmmss"
$zipName = "backup_$(Split-Path $Source -Leaf)_$timestamp.zip"
$zipPath = Join-Path $Destination $zipName

Write-Log "Starting backup: $Source -> $zipPath"

try {
    # Create ZIP archive
    Add-Type -AssemblyName System.IO.Compression.FileSystem
    [System.IO.Compression.ZipFile]::CreateFromDirectory($Source, $zipPath, 'Optimal', $false)

    $size = [math]::Round((Get-Item $zipPath).Length / 1MB, 2)
    Write-Log "Backup completed: $zipPath ($size MB)"

    # Rotate old backups - keep only last N
    $oldBackups = Get-ChildItem $Destination -Filter "backup_*.zip" |
        Sort-Object LastWriteTime -Descending |
        Select-Object -Skip $KeepLast

    foreach ($old in $oldBackups) {
        Remove-Item $old.FullName -Force
        Write-Log "Deleted old backup: $($old.Name)"
    }

    $remaining = (Get-ChildItem $Destination -Filter "backup_*.zip").Count
    Write-Log "Backup rotation complete. $remaining backup(s) retained."

} catch {
    Write-Log "ERROR: $_"
    exit 1
}

Write-Log "--- Backup job finished ---"

Script 5 : Création en masse d’utilisateurs AD à partir d’un fichier CSV

Description

Crée en masse des comptes utilisateurs Active Directory à partir d'un fichier CSV. Gère la génération des mots de passe, le placement dans les unités d'organisation, l'appartenance aux groupes et enregistre toutes les opérations. Idéal pour l'intégration de grands groupes d'utilisateurs.

# Script 5: Bulk AD User Creation from CSV
# Requires: ActiveDirectory module
# CSV format: FirstName,LastName,Department,Title,OU,Groups
# Usage: .Create-ADUsers.ps1 -CsvPath ".users.csv" -DefaultPassword "P@ssw0rd2026!"

param(
    [string]$CsvPath = ".users.csv",
    [string]$DefaultPassword = "TempP@ssw0rd2026!",
    [string]$Domain = "company.local",
    [string]$LogPath = ".user-creation.log"
)

Import-Module ActiveDirectory

$users = Import-Csv $CsvPath
$created = 0; $failed = 0

foreach ($user in $users) {
    $samAccount = ($user.FirstName.Substring(0,1) + $user.LastName).ToLower() -replace 's',''
    $upn = "$samAccount@$Domain"
    $displayName = "$($user.FirstName) $($user.LastName)"

    try {
        # Check if user already exists
        if (Get-ADUser -Filter { SamAccountName -eq $samAccount } -ErrorAction SilentlyContinue) {
            Write-Warning "User $samAccount already exists - skipping"
            continue
        }

        $params = @{
            SamAccountName        = $samAccount
            UserPrincipalName     = $upn
            Name                  = $displayName
            GivenName             = $user.FirstName
            Surname               = $user.LastName
            DisplayName           = $displayName
            Department            = $user.Department
            Title                 = $user.Title
            Path                  = $user.OU
            AccountPassword       = (ConvertTo-SecureString $DefaultPassword -AsPlainText -Force)
            ChangePasswordAtLogon = $true
            Enabled               = $true
        }
        New-ADUser @params

        # Add to groups if specified
        if ($user.Groups) {
            $groups = $user.Groups -split ";"
            foreach ($group in $groups) {
                Add-ADGroupMember -Identity $group.Trim() -Members $samAccount -ErrorAction SilentlyContinue
            }
        }

        $created++
        "$((Get-Date).ToString()) - CREATED: $samAccount ($displayName)" | Out-File $LogPath -Append
        Write-Host "[+] Created: $samAccount" -ForegroundColor Green

    } catch {
        $failed++
        "$((Get-Date).ToString()) - FAILED: $samAccount - $_" | Out-File $LogPath -Append
        Write-Host "[-] Failed: $samAccount - $_" -ForegroundColor Red
    }
}

Write-Host "`n[✓] Done: $created created, $failed failed" -ForegroundColor Cyan
Write-Host "[✓] Log: $LogPath" -ForegroundColor Cyan

Script 6 : Audit des droits d’administrateur local sur toutes les machines

Description

Vérifie l'appartenance au groupe Administrateurs local sur tous les ordinateurs du domaine. Identifie les comptes d'administrateur non autorisés et les entrées frauduleuses, et génère un rapport de conformité. Essentiel pour le renforcement de la sécurité.

# Script 6: Local Admin Audit Across Domain
# Requires: ActiveDirectory module, WinRM enabled on targets
# Usage: .Audit-LocalAdmins.ps1 -OutputPath "C:Reportslocal-admins.csv"

param([string]$OutputPath = ".local-admins-audit.csv")

Import-Module ActiveDirectory

$computers = Get-ADComputer -Filter { OperatingSystem -like "*Windows*" } -Properties OperatingSystem

$results = [System.Collections.Generic.List[PSObject]]::new()

foreach ($computer in $computers) {
    $hostname = $computer.Name
    Write-Host "[*] Checking $hostname..." -NoNewline

    try {
        $admins = Invoke-Command -ComputerName $hostname -ScriptBlock {
            $group = [ADSI]"WinNT://$env:COMPUTERNAME/Administrators,group"
            $group.Members() | ForEach-Object {
                $path = $_.GetType().InvokeMember('ADsPath', 'GetProperty', $null, $_, $null)
                $name = $_.GetType().InvokeMember('Name', 'GetProperty', $null, $_, $null)
                [PSCustomObject]@{
                    Name    = $name
                    AdsPath = $path
                    Type    = if ($path -like "*/$env:COMPUTERNAME/*") { "Local" } else { "Domain" }
                }
            }
        } -ErrorAction Stop

        foreach ($admin in $admins) {
            $results.Add([PSCustomObject]@{
                Computer     = $hostname
                OS           = $computer.OperatingSystem
                AccountName  = $admin.Name
                AccountType  = $admin.Type
                IsDefault    = ($admin.Name -in @("Administrator","Domain Admins"))
                ScanDate     = Get-Date
            })
        }
        Write-Host " $($admins.Count) admins" -ForegroundColor Green

    } catch {
        Write-Host " FAILED: $_" -ForegroundColor Red
    }
}

$results | Export-Csv $OutputPath -NoTypeInformation -Encoding UTF8

# Find non-standard local admins
$suspicious = $results | Where-Object {
    $_.AccountType -eq "Local" -and $_.AccountName -ne "Administrator"
}

Write-Host "`n[!] Suspicious local admins found: $($suspicious.Count)" -ForegroundColor Yellow
$suspicious | Format-Table Computer, AccountName, AccountType -AutoSize
Write-Host "[✓] Full report: $OutputPath" -ForegroundColor Green

Script 7 : Redémarrage automatique des services ayant échoué

Description

Surveille les services critiques sur les serveurs et redémarre automatiquement ceux qui sont arrêtés ou en erreur. Envoie une notification pour chaque redémarrage. S'exécute comme une tâche planifiée toutes les 5 minutes.

# Script 7: Auto-Restart Failed Services
# Requires: PowerShell 7.x
# Usage: .Watch-Services.ps1 -Servers @("srv01","srv02") -Services @("Spooler","W32Time")

param(
    [string[]]$Servers = @("localhost"),
    [string[]]$Services = @("Spooler", "W32Time", "WinRM", "Netlogon"),
    [string]$LogPath = ".service-restarts.log",
    [string]$SmtpServer = "smtp.company.com",
    [string]$AlertTo = "sysadmin@company.com"
)

function Write-Log { param([string]$Msg)
    "$((Get-Date).ToString('yyyy-MM-dd HH:mm:ss')) - $Msg" | Tee-Object -FilePath $LogPath -Append
}

foreach ($server in $Servers) {
    foreach ($svcName in $Services) {
        try {
            $svc = Get-Service -Name $svcName -ComputerName $server -ErrorAction Stop

            if ($svc.Status -ne 'Running') {
                Write-Log "SERVICE DOWN: $svcName on $server (Status: $($svc.Status))"

                # Attempt restart
                $svc | Set-Service -Status Running -ErrorAction Stop
                Start-Sleep -Seconds 3

                # Verify
                $svc.Refresh()
                if ($svc.Status -eq 'Running') {
                    Write-Log "RESTARTED OK: $svcName on $server"
                    Write-Host "[+] Restarted $svcName on $server" -ForegroundColor Green

                    # Send alert
                    Send-MailMessage -SmtpServer $SmtpServer -From "monitoring@company.com" `
                        -To $AlertTo -Subject "✅ Service Restarted: $svcName on $server" `
                        -Body "Service $svcName was found stopped on $server and was automatically restarted at $(Get-Date)."
                } else {
                    Write-Log "RESTART FAILED: $svcName on $server - Status: $($svc.Status)"
                    Write-Host "[-] FAILED to restart $svcName on $server" -ForegroundColor Red
                }
            } else {
                Write-Host "[OK] $svcName on $server - Running" -ForegroundColor Gray
            }
        } catch {
            Write-Log "ERROR checking $svcName on ${server}: $_"
            Write-Host "[ERR] $svcName on $server - $_" -ForegroundColor Red
        }
    }
}

Script 8 : Rapport de disponibilité du serveur

Description

Génère un rapport complet de disponibilité pour tous les serveurs de votre environnement. Affiche la date du dernier redémarrage, la durée de disponibilité en jours et signale les serveurs qui fonctionnent depuis trop longtemps (en attente de correctifs).

# Script 8: Server Uptime Report
# Requires: PowerShell 7.x, WinRM
# Usage: .Get-UptimeReport.ps1 -Servers @("srv01","srv02") -MaxUptimeDays 90

param(
    [string[]]$Servers = @("localhost"),
    [int]$MaxUptimeDays = 90,
    [string]$OutputPath = ".uptime-report.csv"
)

$report = foreach ($server in $Servers) {
    try {
        $os = Get-WmiObject Win32_OperatingSystem -ComputerName $server -ErrorAction Stop
        $lastBoot = $os.ConvertToDateTime($os.LastBootUpTime)
        $uptime = (Get-Date) - $lastBoot
        $days = [math]::Round($uptime.TotalDays, 1)

        [PSCustomObject]@{
            Server      = $server
            LastReboot  = $lastBoot
            UptimeDays  = $days
            UptimeHours = [math]::Round($uptime.TotalHours, 1)
            Status      = if ($days -gt $MaxUptimeDays) { "REBOOT NEEDED" } elseif ($days -gt 30) { "WARNING" } else { "OK" }
            OS          = $os.Caption
        }
    } catch {
        [PSCustomObject]@{
            Server = $server; LastReboot = $null; UptimeDays = -1
            UptimeHours = -1; Status = "UNREACHABLE"; OS = ""
        }
    }
}

$report | Sort-Object UptimeDays -Descending | Format-Table -AutoSize
$report | Export-Csv $OutputPath -NoTypeInformation

$needReboot = $report | Where-Object { $_.Status -eq "REBOOT NEEDED" }
if ($needReboot.Count -gt 0) {
    Write-Host "`n[!] Servers requiring reboot ($MaxUptimeDays+ days uptime):" -ForegroundColor Yellow
    $needReboot | Format-Table Server, UptimeDays, LastReboot -AutoSize
}

Script 9 : Nettoyage des fichiers temporaires (Récupération d’espace disque)

Description

Nettoie en toute sécurité les fichiers temporaires Windows, le cache de préchargement, les caches du navigateur, le cache de Windows Update et les anciens fichiers journaux. Indique l'espace récupéré. Compatible avec tous les ordinateurs Windows.

# Script 9: Temp Files Cleanup
# Requires: PowerShell 7.x (run as Administrator)
# Usage: .Clean-TempFiles.ps1 -WhatIf (dry run) or .Clean-TempFiles.ps1

$ErrorActionPreference = "SilentlyContinue"
$totalFreed = 0

function Remove-Directory {
    param([string]$Path, [string]$Description)
    if (Test-Path $Path) {
        $sizeBefore = (Get-ChildItem $Path -Recurse -Force -ErrorAction SilentlyContinue |
            Measure-Object -Property Length -Sum).Sum
        Get-ChildItem $Path -Recurse -Force -ErrorAction SilentlyContinue | Remove-Item -Recurse -Force
        $freed = [math]::Round($sizeBefore / 1MB, 2)
        $script:totalFreed += $freed
        Write-Host "[+] $Description - Freed: $freed MB" -ForegroundColor Green
    }
}

Write-Host "=== Windows Temp Files Cleanup ===" -ForegroundColor Cyan

# Windows Temp
Remove-Directory "$env:SystemRootTemp" "Windows Temp"
Remove-Directory "$env:TEMP" "User Temp ($env:USERNAME)"

# Prefetch (safe to clear, Windows rebuilds it)
Remove-Directory "$env:SystemRootPrefetch" "Prefetch Cache"

# Windows Update cache
Stop-Service -Name wuauserv -Force
Remove-Directory "$env:SystemRootSoftwareDistributionDownload" "Windows Update Cache"
Start-Service -Name wuauserv

# Thumbnail cache
Remove-Directory "$env:LOCALAPPDATAMicrosoftWindowsExplorer" "Thumbnail Cache"

# Recycle Bin
Clear-RecycleBin -Force -ErrorAction SilentlyContinue
Write-Host "[+] Recycle Bin emptied" -ForegroundColor Green

# Old IIS logs (older than 30 days)
if (Test-Path "C:inetpublogs") {
    $oldLogs = Get-ChildItem "C:inetpublogs" -Recurse -Filter "*.log" |
        Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-30) }
    $oldLogs | Remove-Item -Force
    Write-Host "[+] Removed $($oldLogs.Count) old IIS log files" -ForegroundColor Green
}

Write-Host "`n[✓] Total disk space recovered: $([math]::Round($totalFreed, 2)) MB" -ForegroundColor Cyan

Script 10 : Vérification de l’expiration du certificat SSL

Description

Vérifie les dates d'expiration des certificats SSL d'une liste de serveurs/sites web. Envoie des alertes lorsque les certificats expirent dans le délai configuré (30 jours par défaut). Exécutez cette vérification chaque semaine pour éviter les mauvaises surprises.

# Script 10: SSL Certificate Expiry Checker
# Requires: PowerShell 7.x
# Usage: .Check-SSLCerts.ps1 -Hosts @("google.com","mysite.com") -AlertDays 30

param(
    [string[]]$Hosts = @("google.com", "microsoft.com"),
    [int]$AlertDays = 30,
    [int]$Port = 443,
    [string]$SmtpServer = "smtp.company.com",
    [string]$AlertTo = "sysadmin@company.com"
)

$results = [System.Collections.Generic.List[PSObject]]::new()

foreach ($hostname in $Hosts) {
    try {
        $tcpClient = New-Object Net.Sockets.TcpClient($hostname, $Port)
        $sslStream = New-Object Net.Security.SslStream($tcpClient.GetStream(), $false,
            { $true })  # Accept all certs for inspection
        $sslStream.AuthenticateAsClient($hostname)

        $cert = $sslStream.RemoteCertificate
        $cert2 = New-Object Security.Cryptography.X509Certificates.X509Certificate2($cert)
        $expiry = $cert2.NotAfter
        $daysLeft = [math]::Round(($expiry - (Get-Date)).TotalDays)

        $results.Add([PSCustomObject]@{
            Host       = $hostname
            Expiry     = $expiry
            DaysLeft   = $daysLeft
            Issuer     = $cert2.Issuer
            Subject    = $cert2.Subject
            Status     = if ($daysLeft -lt 0) { "EXPIRED" } elseif ($daysLeft -lt $AlertDays) { "EXPIRING SOON" } else { "OK" }
        })

        $color = if ($daysLeft -lt 0) { "Red" } elseif ($daysLeft -lt $AlertDays) { "Yellow" } else { "Green" }
        Write-Host "[$($results[-1].Status)] $hostname - Expires: $($expiry.ToString('yyyy-MM-dd')) ($daysLeft days)" -ForegroundColor $color

        $sslStream.Dispose()
        $tcpClient.Dispose()

    } catch {
        $results.Add([PSCustomObject]@{
            Host = $hostname; Expiry = $null; DaysLeft = -999
            Issuer = ""; Subject = ""; Status = "ERROR: $_"
        })
        Write-Host "[ERROR] $hostname - $_" -ForegroundColor Red
    }
}

# Alert on expiring certs
$alertCerts = $results | Where-Object { $_.Status -ne "OK" }
if ($alertCerts.Count -gt 0) {
    $body = $alertCerts | ConvertTo-Html -Title "SSL Certificate Alerts" | Out-String
    Send-MailMessage -SmtpServer $SmtpServer -From "ssl-monitor@company.com" `
        -To $AlertTo -Subject "🔒 SSL Certificate Alert - $($alertCerts.Count) cert(s) expiring" `
        -Body $body -BodyAsHtml -Priority High
    Write-Host "`n[!] Alert email sent!" -ForegroundColor Red
}

$results | Format-Table Host, DaysLeft, Expiry, Status -AutoSize

Planification de scripts avec le planificateur de tâches

Pour automatiser ces scripts, utilisez le Planificateur de tâches Windows. Voici comment créer une tâche planifiée via PowerShell :

# Create a scheduled task to run disk space monitor every hour
$action = New-ScheduledTaskAction -Execute "pwsh.exe" `
    -Argument "-NonInteractive -File C:ScriptsMonitor-DiskSpace.ps1"

$trigger = New-ScheduledTaskTrigger -RepetitionInterval (New-TimeSpan -Hours 1) -Once -At (Get-Date)

$settings = New-ScheduledTaskSettingsSet -RunOnlyIfNetworkAvailable -WakeToRun

$principal = New-ScheduledTaskPrincipal -UserId "SYSTEM" -RunLevel Highest

Register-ScheduledTask -TaskName "DiskSpaceMonitor" `
    -Action $action -Trigger $trigger -Settings $settings `
    -Principal $principal -Description "Monitors disk space and sends alerts"

Write-Host "[✓] Scheduled task created successfully" -ForegroundColor Green

Conclusion

Ces 10 scripts PowerShell couvrent les tâches d'administration système les plus courantes et critiques sous Windows. Chaque script est prêt pour la production et peut être adapté à votre environnement spécifique en ajustant ses paramètres.

Pour tirer le meilleur parti de l'automatisation PowerShell, il est essentiel de constituer une bibliothèque de scripts personnelle, de planifier les tâches de manière appropriée et de combiner ces scripts en flux de travail plus importants à l'aide de modules PowerShell.

Explorez des milliers d'autres scripts communautaires sur PowerShell Gallery et envisagez de créer vos propres modules publiés sur PSGallery à mesure que votre bibliothèque s'étoffe. Grâce à sa nature multiplateforme (version 7.x), ces scripts fonctionnent aussi bien sur Windows Server que sur Linux ou macOS, ce qui en fait des outils véritablement universels pour tout administrateur système.