Introduction
Dans le domaine de la gestion informatique, la conservation du journal des événements du système précis est essentielle pour le dépannage, la conformité et la sécurité. Cependant, la gestion manuelle de ces journaux peut prendre beaucoup de temps, en particulier dans les grands environnements. Pour y remédier, l’automatisation de la sauvegarde des journaux d’événements à l’aide de PowerShell est une solution pratique et efficace. Ce guide présente un script PowerShell efficace conçu pour exporter et compresser les journaux d’événements, offrant ainsi une approche rationalisée de la gestion des journaux d’événements.
Contexte
Les journaux d’événements sont essentiels pour comprendre l’activité du système et diagnostiquer les problèmes. Ces journaux enregistrent des informations telles que les erreurs système, les failles de sécurité et les événements liés aux applications, ce qui les rend inestimables pour les administrateurs système et les fournisseurs de services gérés (MSP). Le script fourni automatise le processus de sauvegarde, garantissant que les journaux sont exportés, compressés et stockés en toute sécurité sans nécessiter d’intervention manuelle.
Ce script est particulièrement utile pour les environnements soumis à des exigences réglementaires strictes, telles que la HIPAA ou la RGPD, où le maintien de pistes d’audit détaillées est obligatoire.
Le script :
#Requires -Version 5.1 <# .SYNOPSIS Exports the specified event logs to a specified location in a compressed zip file. .DESCRIPTION Exports the specified event logs to a specified location in a compressed zip file. The event logs can be exported from a specific date range. By using this script, you indicate your acceptance of the following legal terms as well as our Terms of Use at https://www.ninjaone.com/terms-of-use. Ownership Rights: NinjaOne owns and will continue to own all right, title, and interest in and to the script (including the copyright). NinjaOne is giving you a limited license to use the script in accordance with these legal terms. Use Limitation: You may only use the script for your legitimate personal or internal business purposes, and you may not share the script with another party. Republication Prohibition: Under no circumstances are you permitted to re-publish the script in any script library or website belonging to or under the control of any other software provider. Warranty Disclaimer: The script is provided “as is” and “as available”, without warranty of any kind. NinjaOne makes no promise or guarantee that the script will be free from defects or that it will meet your specific needs or expectations. Assumption of Risk: Your use of the script is at your own risk. You acknowledge that there are certain inherent risks in using the script, and you understand and assume each of those risks. Waiver and Release: You will not hold NinjaOne responsible for any adverse or unintended consequences resulting from your use of the script, and you waive any legal or equitable rights or remedies you may have against NinjaOne relating to your use of the script. EULA: If you are a NinjaOne customer, your use of the script is subject to the End User License Agreement applicable to you (EULA). PARAMETER: -EventLogs "System,Security" -BackupDestination "C:\Temp\EventLogs\" Exports the specified event logs to a specified location in a compressed zip file. .EXAMPLE -EventLogs "System,Security" -BackupDestination "C:\Temp\EventLogs\" ## EXAMPLE OUTPUT WITH EventLogs ## [Info] Today is 2023-04-17 [Info] EventLogs are System,Security [Info] Backup Destination is C:\Temp\EventLogs\ [Info] Start Date is null [Info] End Date is null [Info] Exporting Event Logs... [Info] Exported Event Logs to C:\Temp\EventLogs\System.evtx [Info] Exported Event Logs to C:\Temp\EventLogs\Security.evtx [Info] Successfully exported Event Logs! [Info] Compressing Event Logs... [Info] Compressed Event Logs to C:\Temp\EventLogs\Backup-System-Security-2023-04-17.zip [Info] Successfully compressed Event Logs! [Info] Removing Temporary Event Logs... [Info] Removed Temporary Event Logs! PARAMETER: -EventLogs "System,Security" -BackupDestination "C:\Temp\EventLogs\" -StartDate "2023-04-15" -EndDate "2023-04-15" Exports the specified event logs to a specified location in a compressed zip file. The event logs can be exported from a specific date range. .EXAMPLE -EventLogs "System,Security" -BackupDestination "C:\Temp\EventLogs\" -StartDate "2023-04-15" -EndDate "2023-04-15" ## EXAMPLE OUTPUT WITH StartDate and EndDate ## [Info] Today is 2023-04-17 [Info] EventLogs are System,Security [Info] Backup Destination is C:\Temp\EventLogs\ [Info] Start Date is 2023-04-15 [Info] End Date is 2023-04-16 [Info] Exporting Event Logs... [Info] Exported Event Logs to C:\Temp\EventLogs\System.evtx [Info] Exported Event Logs to C:\Temp\EventLogs\Security.evtx [Info] Successfully exported Event Logs! [Info] Compressing Event Logs... [Info] Compressed Event Logs to C:\Temp\EventLogs\Backup-System-Security-2023-04-17.zip [Info] Successfully compressed Event Logs! [Info] Removing Temporary Event Logs... [Info] Removed Temporary Event Logs! .NOTES Minimum OS Architecture Supported: Windows 10, Windows Server 2016 Release Notes: Initial Release #> [CmdletBinding()] param ( [String]$EventLogs, [String]$BackupDestination, [DateTime]$StartDate, [DateTime]$EndDate ) begin { function Test-IsElevated { $id = [System.Security.Principal.WindowsIdentity]::GetCurrent() $p = New-Object System.Security.Principal.WindowsPrincipal($id) $p.IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator) } } process { if (-not (Test-IsElevated)) { Write-Host "[Error] Access Denied. Please run with Administrator privileges." exit 1 } if ($env:eventLogs -and $env:eventLogs -notlike "null") { $EventLogs = $env:eventLogs } $EventLogNames = $EventLogs -split "," | ForEach-Object { $_.Trim() } if ($env:backupDestination -and $env:backupDestination -notlike "null") { $BackupDestination = $env:backupDestination } if ($env:startDate -and $env:startDate -notlike "null") { $StartDate = $env:startDate } if ($env:endDate -and $env:endDate -notlike "null") { $EndDate = $env:endDate } # Validate StartDate and EndDate if ($StartDate) { try { $StartDate = Get-Date -Date $StartDate -ErrorAction Stop } catch { Write-Host "[Error] The specified start date is not a valid date." exit 1 } } if ($EndDate) { try { $EndDate = Get-Date -Date $EndDate -ErrorAction Stop } catch { Write-Host "[Error] The specified end date is not a valid date." exit 1 } } # Validate BackupDestination is a valid path to a folder if ($(Test-Path -Path $BackupDestination -PathType Container -ErrorAction SilentlyContinue)) { $BackupDestination = Get-Item -Path $BackupDestination } else { try { $BackupDestination = New-Item -Path $BackupDestination -ItemType Directory -ErrorAction Stop } catch { Write-Host "[Error] The specified backup destination is not a valid path to a folder." exit 1 } } Write-Host "[Info] Today is $(Get-Date -Format yyyy-MM-dd-HH-mm)" # Validate EventLogs are valid event logs if ( $( wevtutil.exe el | ForEach-Object { if ($EventLogNames -and $($EventLogNames -contains $_ -or $EventLogNames -like $_)) { $_ } } ).Count -eq 0 ) { Write-Host "[Error] No Event Logs matching: $EventLogNames" } Write-Host "[Info] EventLogs are $EventLogNames" if ($EventLogNames -and $EventLogNames.Count -gt 0) { Write-Host "[Info] Backup Destination is $BackupDestination" # If the start date is specified, check if it's a valid date if ($StartDate) { try { $StartDate = $(Get-Date -Date $StartDate).ToUniversalTime() } catch { Write-Host "[Error] The specified start date is not a valid date." exit 1 } Write-Host "[Info] Start Date is $(Get-Date -Date $StartDate -Format yyyy-MM-dd-HH-mm)" } else { Write-Host "[Info] Start Date is null" } if ($EndDate) { try { $EndDate = $(Get-Date -Date $EndDate).ToUniversalTime() } catch { Write-Host "[Error] The specified end date is not a valid date." exit 1 } Write-Host "[Info] End Date is $(Get-Date -Date $EndDate -Format yyyy-MM-dd-HH-mm)" } else { Write-Host "[Info] End Date is null" } # Check if the start date after the end date if ($StartDate -and $EndDate -and $StartDate -gt $EndDate) { # Flip the dates if the start date is after the end date $OldEndDate = $EndDate $OldStartDate = $StartDate $EndDate = $OldStartDate $StartDate = $OldEndDate Write-Host "[Info] Start Date is after the end date. Flipping dates." } Write-Host "[Info] Exporting Event Logs..." foreach ($EventLog in $EventLogNames) { $EventLogPath = $(Join-Path -Path $BackupDestination -ChildPath "$EventLog.evtx") try { if ($StartDate -and $EndDate) { wevtutil.exe epl "$EventLog" "$EventLogPath" /ow:true /query:"*[System[TimeCreated[@SystemTime>='$(Get-Date -Date $StartDate -UFormat "%Y-%m-%dT%H:%M:%S")' and @SystemTime<='$(Get-Date -Date $EndDate -UFormat "%Y-%m-%dT%H:%M:%S")']]]" 2>$null } elseif ($StartDate) { wevtutil.exe epl "$EventLog" "$EventLogPath" /ow:true /query:"*[System[TimeCreated[@SystemTime>='$(Get-Date -Date $StartDate -UFormat "%Y-%m-%dT%H:%M:%S")']]]" 2>$null } elseif ($EndDate) { wevtutil.exe epl "$EventLog" "$EventLogPath" /ow:true /query:"*[System[TimeCreated[@SystemTime<='$(Get-Date -Date $EndDate -UFormat "%Y-%m-%dT%H:%M:%S")']]]" 2>$null } else { wevtutil.exe epl "$EventLog" "$EventLogPath" /ow:true /query:"*[System[TimeCreated[@SystemTime>='1970-01-01T00:00:00']]]" 2>$null } if ($(Test-Path -Path $EventLogPath -ErrorAction SilentlyContinue)) { # Get the number of events in the log $EventCount = $(Get-WinEvent -Path $EventLogPath -ErrorAction SilentlyContinue).Count if ($EventCount -and $EventCount -gt 0) { Write-Host "[Info] Found $EventCount events from $EventLog" } else { Write-Host "[Warn] No events found in $EventLog" continue } Write-Host "[Info] Exported Event Logs to $EventLogPath" } else { throw } } catch { Write-Host "[Error] Failed to export event logs $EventLog" continue } } Write-Host "[Info] Compressing Event Logs..." # Get the event log paths that where created $JoinedPaths = foreach ($EventLog in $EventLogNames) { # Join the Backup Destination and the Event Log Name $JoinedPath = Join-Path -Path $BackupDestination -ChildPath "$EventLog.evtx" -ErrorAction SilentlyContinue if ($(Test-Path -Path $JoinedPath -ErrorAction SilentlyContinue)) { # Get the saved event log path Get-Item -Path $JoinedPath -ErrorAction SilentlyContinue } } $JoinedPaths = $JoinedPaths | Where-Object { $(Test-Path -Path $_ -ErrorAction SilentlyContinue) } try { # Create a destination path to save the compressed file to # <Folder>Backup-<EventLogName-EventLogName>-<Date>.zip $Destination = Join-Path -Path $($BackupDestination) -ChildPath $( @( "Backup-", $($EventLogNames -join '-'), "-", $(Get-Date -Format yyyy-MM-dd-HH-mm), ".zip" ) -join '' ) $CompressArchiveSplat = @{ Path = $JoinedPaths DestinationPath = $Destination Update = $true } # # If the destination path already exists, update the archive instead of creating a new one # if ($(Test-Path -Path $Destination -ErrorAction SilentlyContinue)) { # $CompressArchiveSplat.Add("Update", $true) # } # Compress the Event Logs $CompressError = $true $ErrorCount = 0 $SecondsToSleep = 1 $TimeOut = 120 while ($CompressError) { try { $CompressError = $false Compress-Archive @CompressArchiveSplat -ErrorAction Stop break } catch { $CompressError = $true } if ($CompressError) { if ($ErrorCount -gt $TimeOut) { Write-Host "[Warn] Skipping compression... Timed out." } if ($ErrorCount -eq 0) { Write-Host "[Info] Waiting for wevtutil.exe to close file." } Start-Sleep -Seconds $SecondsToSleep } $ErrorCount++ } if ($CompressError) { Write-Host "[Error] Failed to Compress Event Logs." } else { Write-Host "[Info] Compressed Event Logs to $($Destination)" } } catch { Write-Host "[Error] Failed to compress event logs." } if ($(Test-Path -Path $Destination -ErrorAction SilentlyContinue)) { Write-Host "[Info] Removing Temporary Event Logs..." foreach ($EventLogPath in $JoinedPaths) { try { Remove-Item -Path $EventLogPath -Force -ErrorAction SilentlyContinue Write-Host "[Info] Removed Temporary Event Logs: $EventLogPath" } catch {} } } else { Write-Host "[Info] Renaming Event Logs..." foreach ($EventLogPath in $JoinedPaths) { if ($(Test-Path -Path $EventLogPath -ErrorAction SilentlyContinue)) { try { $NewPath = Rename-Item -Path $EventLogPath -NewName "$($EventLogPath.BaseName)-$(Get-Date -Format yyyy-MM-dd-HH-mm).evtx" -PassThru -ErrorAction Stop Write-Host "[Info] Event Logs saved to: $NewPath" } catch { Write-Host "[Info] Event Logs saved to: $EventLogPath" } } else { Write-Host "[Info] Event Logs saved to: $EventLogPath" } } } } else { Write-Host "[Error] No Event Logs were specified." exit 1 } } end { }
Gagnez du temps grâce à plus de 300 scripts du Dojo NinjaOne.
Description détaillée
Le script est structuré de manière à atteindre les objectifs suivants :
- Exporter les journaux d’événements : pour extraire des journaux spécifiques (par exemple, système, sécurité) en fonction des données fournies par l’administrateur.
- Filtrage des dates : il est possible de filtrer les journaux en fonction des dates de début et de fin.
- Compression : pour enregistrer les journaux exportés sous la forme d’un fichier .zip compressé afin d’optimiser le stockage.
- Nettoyage : pour supprimer les fichiers journaux temporaires après la compression.
Composants clés
1. Contrôles préliminaires
- Privilèges administrateur : la fonction Test-IsElevated permet de s’assurer que le script est exécuté avec des autorisations élevées.
- Validation des entrées : valide les entrées de l’utilisateur pour les journaux d’événements, les dates et la destination de la sauvegarde.
2. Exportation des journaux
- Les journaux sont exportés à l’aide de wevtutil.exe.
- Le script permet de filtrer les dates à l’aide de la fonction Get-Date de PowerShell pour une extraction précise des journaux.
- Produit des fichiers .evtx dans le répertoire de sauvegarde spécifié.
3. Compression
- La commande Compress-Archive est utilisée pour regrouper les journaux exportés dans un fichier .zip.
- Le fichier compressé est nommé dynamiquement pour inclure les noms des journaux d’événements et la date du jour.
4. Nettoyage
- Les fichiers .evtx temporaires sont supprimés après une compression réussie pour économiser de l’espace.
Cas d’utilisation potentiels de la sauvegarde du journal des événements
Étude de cas : Gestion des journaux pour les MSP
Un fournisseur de services gérés (MSP) supervise 100 machines clientes. Pour se conformer aux exigences réglementaires, les journaux doivent être sauvegardés chaque semaine. En utilisant ce script :
- Le MSP planifie le script via le planificateur de tâches pour qu’il s’exécute tous les dimanches.
- Les journaux de “Système” et de “Sécurité” sont exportés pour la semaine et sauvegardés dans un référentiel de sauvegarde central.
- Les sauvegardes compressées sont archivées, ce qui libère de l’espace de stockage tout en garantissant l’accès aux journaux pour les audits.
Comparaisons
Méthode manuelle
- Chronophage : l’exportation et la compression manuelles des journaux nécessitent des efforts importants.
- Sujet à erreur : risque accru d’absence de journaux ou de création de sauvegardes incomplètes.
Utilisation d’outils tiers
- Avantages : des outils tels que Splunk offrent des analyses avancées mais peuvent être coûteux.
- Avantages du script : ce script PowerShell est gratuit, personnalisable et s’intègre parfaitement dans les environnements Windows existants.
FAQ
Quels journaux d’événements ce script peut-il sauvegarder ?
Le script prend en charge tous les journaux disponibles via wevtutil.exe, tels que les journaux du système, de la sécurité et des applications.
Puis-je programmer ce script ?
Oui, utilisez le planificateur de tâches pour automatiser le script des sauvegardes régulières.
Comment fonctionne le filtrage par date ?
Indiquez les dates de début et de fin pour extraire les journaux d’une période spécifique. Le script valide et inverse les dates si nécessaire.
Que se passe-t-il si le script rencontre une erreur ?
Les erreurs, telles que les chemins d’accès non valides ou les journaux manquants, sont enregistrées et gérées de manière élégante afin d’éviter l’arrêt du script.
Implications
L’automatisation des sauvegardes des journaux d’événements à l’aide de ce script renforce la sécurité informatique en garantissant l’archivage cohérent des journaux. Il soutient également les efforts de mise en conformité en conservant des enregistrements accessibles et horodatés. De plus, en cas de violation ou de défaillance du système, ces sauvegardes peuvent être essentielles pour l’analyse des erreurs.
Recommandations
- Exécutez en tant qu’administrateur : garantissez des privilèges élevés pour accéder à tous les journaux d’événements.
- Planifiez des sauvegardes régulières : utilisez le planificateur de tâches ou des outils similaires pour automatiser les sauvegardes périodiques.
- Emplacements de sauvegarde sécurisés : stockez les journaux compressés dans un endroit sûr, de préférence chiffré, afin d’éviter tout accès non autorisé.
- Testez avant de déployer : exécutez le script dans un environnement de test pour valider sa fonctionnalité.
Conclusion
La gestion des journaux d’événements fait partie intégrante des opérations informatiques, et l’automatisation de ce processus à l’aide de PowerShell simplifie une tâche généralement fastidieuse. Ce script garantit non seulement des sauvegardes cohérentes, mais il offre également la possibilité de personnaliser et d’adapter les sauvegardes à des environnements variés.
Pour les MSP et les professionnels de l’informatique à la recherche de solutions de gestion informatique complètes, NinjaOne propose des outils qui complètent les scripts de ce type, permettant de rationaliser les opérations informatiques et de renforcer la sécurité.