From 469e6f7aa435460be5bf00ea40b087c2be4eeb48 Mon Sep 17 00:00:00 2001 From: P6g9YHK6 <17877371+P6g9YHK6@users.noreply.github.com> Date: Fri, 6 Jun 2025 08:44:38 +0200 Subject: [PATCH 01/23] Update file: Mail notification password expiry.ps1 --- .../Mail notification password expiry.ps1 | 967 +++++++++--------- 1 file changed, 497 insertions(+), 470 deletions(-) diff --git a/scripts_staging/Backend/Mail notification password expiry.ps1 b/scripts_staging/Backend/Mail notification password expiry.ps1 index ba4227fd..94d8c374 100644 --- a/scripts_staging/Backend/Mail notification password expiry.ps1 +++ b/scripts_staging/Backend/Mail notification password expiry.ps1 @@ -1,482 +1,509 @@ -<# +<# .SYNOPSIS - Script permettant de récupérer et analyser les utilisateurs dont le mot de passe est sur le point d'expirer dans Active Directory. + Ensures the script is executed using PowerShell 7 or higher. + .DESCRIPTION - Ce script se connecte à Active Directory pour rechercher les utilisateurs dans une unité organisationnelle spécifiée. - Il récupère la date de dernière mise à jour du mot de passe pour chaque utilisateur et la compare à la politique de mot de passe du domaine. - En fonction du nombre de jours restant avant l'expiration, les comptes sont classés en trois catégories : - - Expiré : Le mot de passe a déjà expiré. - - Critique : Le mot de passe est très proche de l'expiration, selon le seuil critique configuré. - - Avertissement : Le mot de passe approche de l'expiration, selon le seuil d'avertissement configuré. - Le script génère un rapport HTML contenant : - • Les détails de la politique de mot de passe du domaine (durée maximale, durée minimale, longueur minimale, complexité, historique et seuils de verrouillage). - • Un résumé statistique indiquant le nombre d'utilisateurs par catégorie. - • Une liste détaillée des comptes répartis par catégorie. - Les options de test ont été supprimées. -.PARAMETER TargetOU - Spécifie l'OU dans laquelle rechercher les utilisateurs. Exemple : "OU=Utilisateurs,DC=domaine,DC=local". -.PARAMETER WarningThreshold - Nombre de jours avant expiration déclenchant un avertissement (par défaut : 15). -.PARAMETER CriticalThreshold - Nombre de jours avant expiration déclenchant une alerte critique (par défaut : 7). -.PARAMETER IncludeDisabled - Indique si les comptes désactivés doivent être inclus dans le rapport (false par défaut). -.PARAMETER IncludeNeverExpires - Indique si les comptes dont le mot de passe n'expire jamais doivent être inclus dans le rapport (false par défaut). -.EXAMPLE - .\Check-PasswordExpiration.ps1 -TargetOU "OU=Utilisateurs,DC=domaine,DC=local" - Exécute le script avec l'OU spécifiée et les seuils par défaut. -.EXAMPLE - .\Check-PasswordExpiration.ps1 -TargetOU "OU=Utilisateurs,DC=domaine,DC=local" -WarningThreshold 20 -CriticalThreshold 10 - Exécute le script avec des seuils personnalisés pour les alertes d’avertissement et critiques. + This script verifies whether it is running in a PowerShell 7+ environment. + If not, and if PowerShell 7 (pwsh) is available on the system, it re-invokes itself using pwsh, passing along any parameters. + If pwsh is not found, the script outputs a message and exits with an error code. + Once running in PowerShell 7 or higher, it sets the output rendering mode to plaintext for consistent formatting. + .NOTES - Author: Peter Quellennec - Date: 27/05/25 + Author: PQU + Date: 29/04/2025 #public -#> -{{CallPowerShell7Lite}} - -$TargetOU = $env:TARGET_OU -$SmtpServer = $env:SMTP_SERVER -$SmtpPort = [int]$env:SMTP_PORT -$AdminEmail = $env:ADMIN_EMAIL -$FromEmail = $env:FROM_EMAIL -$signmail = $env:SIGNMAIL -$WarningThreshold = [int]$env:WARNING_THRESHOLD -$CriticalThreshold = [int]$env:CRITICAL_THRESHOLD -$EmailSignature = $env:EMAIL_SIGNATURE - -function Convert-ToBoolean($value) { - return $value -match '^(1|true|yes)$' -} - -$IncludeDisabled = Convert-ToBoolean $env:INCLUDE_DISABLED -$IncludeNeverExpires = Convert-ToBoolean $env:INCLUDE_NEVER_EXPIRES -$GenerateReportOnly = Convert-ToBoolean $env:GENERATE_REPORT_ONLY - -if ($env:SMTP_CREDENTIAL_USERNAME -and $env:SMTP_CREDENTIAL_PASSWORD) { - try { - $SecurePassword = ConvertTo-SecureString $env:SMTP_CREDENTIAL_PASSWORD -AsPlainText -Force - $SmtpCredential = New-Object System.Management.Automation.PSCredential ($env:SMTP_CREDENTIAL_USERNAME, $SecurePassword) - } catch { - Write-Error "Failed to create SMTP credentials: $_" - } -} - -function Test-Prerequisites { - - $adFeature = Get-WindowsFeature -Name AD-Domain-Services -ErrorAction Stop - if ($adFeature.InstallState -ne 'Installed') { - Write-Error "AD Domain Services ne sont pas installés. Arrêt du script." - exit 1 - } - - if (-not $SmtpServer -or -not $SmtpPort) { - Write-Error "Les variables `$SmtpServer et `$SmtpPort doivent être définies avant d'appeler cette fonction." - exit 1 - } - - if (-not (Get-Module -ListAvailable -Name ActiveDirectory)) { - Write-Error "Module ActiveDirectory non trouvé. Arrêt du script." - exit 1 - } - - Import-Module ActiveDirectory -ErrorAction Stop - - try { - $dc = Get-ADDomainController -Discover -ErrorAction Stop - Write-Host "Connexion réussie au contrôleur de domaine : $($dc.HostName)" - } - catch { - Write-Error "Impossible de se connecter au contrôleur de domaine. Arrêt du script." - exit 1 - } - - try { - $tcpClient = New-Object System.Net.Sockets.TcpClient - $tcpClient.Connect($SmtpServer, $SmtpPort) - $tcpClient.Close() - Write-Host "Connexion réussie au serveur SMTP : $SmtpServer":"$SmtpPort" - } - catch { - Write-Error "Impossible de se connecter au serveur SMTP : $SmtpServer sur le port $SmtpPort. Arrêt du script." - exit 1 - } -} -function Get-UserPasswordExpirationInfo { - param ( - $user, - $maxPasswordAge - ) - - $result = [PSCustomObject]@{ - Name = $user.Name - SamAccountName = $user.SamAccountName - Email = $user.EmailAddress - ExpirationDate = $null - DaysLeft = $null - Status = "OK" - Enabled = $user.Enabled - PasswordNeverExpires = $user.PasswordNeverExpires - } - - if ($user.PasswordLastSet -eq $null) { - $result.Status = "NeverLoggedIn" - return $result - } - - if ($user.PasswordNeverExpires) { - $result.Status = "NeverExpires" - return $result - } - - $passwordExpirationDate = $user.PasswordLastSet + $maxPasswordAge - $daysLeft = ($passwordExpirationDate - (Get-Date)).Days - - $result.ExpirationDate = $passwordExpirationDate - $result.DaysLeft = $daysLeft - - if ($daysLeft -lt 0) { - $result.Status = "Expired" - } - elseif ($daysLeft -le $CriticalThreshold) { - $result.Status = "Critical" - } - elseif ($daysLeft -le $WarningThreshold) { - $result.Status = "Warning" - } - - return $result -} +.CHANGELOG + 22.05.25 SAN Added UTF8 to fix encoding issue with russian & french chars + 06.06.25 PQU Added support for multiple admin emails +#> -function ConvertTo-HtmlReport { - param ( - $expiredUsers, - $criticalUsers, - $warningUsers, - $neverExpiresUsers, - $neverLoggedInUsers, - $disabledUsers, - $targetOU, - $passwordPolicy, - $warningThreshold, - $criticalThreshold - ) - $html = @" - - -
-Durée maximale du mot de passe: $($passwordPolicy.MaxPasswordAge.Days) jours
-Durée minimale du mot de passe: $($passwordPolicy.MinPasswordAge.Days) jours
-Longueur minimale: $($passwordPolicy.MinPasswordLength) caractères
-Complexité requise: $($passwordPolicy.ComplexityEnabled)
-Historique du mot de passe: $($passwordPolicy.PasswordHistoryCount) mots de passe
-Verrouillage de compte: $($passwordPolicy.LockoutThreshold) tentatives (durée: $($passwordPolicy.LockoutDuration.Minutes) minutes, observation: $($passwordPolicy.LockoutObservationWindow.Minutes) minutes)
-Seuil d'avertissement : $warningThreshold jours
-Seuil critique : $criticalThreshold jours
-Statistiques : - Expirés: $($expiredUsers.Count) - Critiques: $($criticalUsers.Count) - Avertissement: $($warningUsers.Count) - Expirent jamais: $($neverExpiresUsers.Count) - Jamais connectés: $($neverLoggedInUsers.Count) - Désactivés: $($disabledUsers.Count) -
-Durée maximale du mot de passe: $($passwordPolicy.MaxPasswordAge.Days) jours
+Durée minimale du mot de passe: $($passwordPolicy.MinPasswordAge.Days) jours
+Longueur minimale: $($passwordPolicy.MinPasswordLength) caractères
+Complexité requise: $($passwordPolicy.ComplexityEnabled)
+Historique du mot de passe: $($passwordPolicy.PasswordHistoryCount) mots de passe
+Verrouillage de compte: $($passwordPolicy.LockoutThreshold) tentatives (durée: $($passwordPolicy.LockoutDuration.Minutes) minutes, observation: $($passwordPolicy.LockoutObservationWindow.Minutes) minutes)
+Seuil d'avertissement : $warningThreshold jours
+Seuil critique : $criticalThreshold jours
+Statistiques : + Expirés: $($expiredUsers.Count) + Critiques: $($criticalUsers.Count) + Avertissement: $($warningUsers.Count) + Expirent jamais: $($neverExpiresUsers.Count) + Jamais connectés: $($neverLoggedInUsers.Count) + Désactivés: $($disabledUsers.Count) +
+Généré le : $(Get-Date -Format "dd/MM/yyyy HH:mm")
+ + "@ - - if ($expiredUsers) { - $html += "Généré le : $(Get-Date -Format "dd/MM/yyyy HH:mm")
- - + + return $html + } + + function Get-EmailSignature { + if ($EmailSignature) { + return "
+ Service Informatique
+ Téléphone : +33 (0)1 XX XX XX XX
+ Email : support@domain.com
+ Ce message est généré automatiquement, merci de ne pas y répondre directement.
+
- Service Informatique
- Téléphone : +33 (0)1 XX XX XX XX
- Email : support@domain.com
- Ce message est généré automatiquement, merci de ne pas y répondre directement.
-
') { + $bodyWithSignature = $Body -replace '(?i)', "$signature" + } else { + $bodyWithSignature = "$Body$signature" + } + + $mailMessage = New-Object System.Net.Mail.MailMessage + $mailMessage.From = $FromAddress + foreach ($recipient in $Recipients) { $mailMessage.To.Add($recipient) } + $mailMessage.Subject = $Subject + $mailMessage.Body = $bodyWithSignature + $mailMessage.IsBodyHtml = $true + if ($Attachments) { + foreach ($att in $Attachments) { + $mailMessage.Attachments.Add((New-Object System.Net.Mail.Attachment($att))) + } + } + $smtpClient = New-Object System.Net.Mail.SmtpClient($SmtpServer, $Port) + if ($SmtpCredential) { + $smtpClient.Credentials = $SmtpCredential + } + try { + $smtpClient.Send($mailMessage) + Write-Host "Email sent successfully." + } + catch { + Write-Error "Failed to send email: $_" + } + } + + function Send-UserNotification { + param( + [string]$Recipient, + [string]$Subject, + [string]$Body, + [string]$SmtpServer, + [int]$Port = 25, + [string]$FromAddress + ) + + $signature = Get-EmailSignature + $bodyWithSignature = $Body + if ($Body -match '(?i)') { + $bodyWithSignature = $Body -replace '(?i)', "$signature" + } else { + $bodyWithSignature = @" + + +
+ + +
+