07 Jun 2021, 00:00

Envoi d'un mail d'avertissement lorsque le mot passe AD est proche de l'expiration

Share

Préambule

Le but est d’avertir les utilisateurs d’un domaine Active Directory lorsque leur mot de passe est proche de l’expiration, pour leur permettre de le renouveler avant l’expiration.

Le renouvellemnt se fait sans problème lorsque l’on est connecté directement au réseau, mais dans le cas d’un accès via OpenVPN avec authentification auprès de l’AD, la connexion VPN sera bloquée lorsque le mot de passe est expiré. D’où la procédure ici-présente.

Stockage du mot de passe de manière chiffrée

Source

Le but, si je comprends bien, est d’enregistrer une empreinte du mot de passe (ou le mot de passe chiffré) dans un fichier, pour qu’il soit utilisable sans interaction humaine, sans pour autant être exposé en clair sur le disque.

Le fichier obtenu sera spécifique à ce compte utilisateur, et cette machine. Il devra être recréé si l’opération doit être effectuée depuis un autre compte, ou le même compte sur une autre machine.

Lancer powershell, puis les commandes suivantes (adapter le chemin de fichier si besoin) :

$credential = Get-Credential # entrer identifiant et mot de passe à conserver
$credential.Password | ConvertFrom-SecureString | Set-Content D:\encrypted_password.txt

Le fichier D:\encrypted_password.txt contient le hash qui nous intéresse.

À noter que ceci a été réalisé en utilisant un utilisateur qui possède une licence valide auprès d’Office 365. Non testé auprès d’autres fournisseurs SMTP.

Script pour générer et envoyer les mails

Il s’agit du script de Robert Pearman que j’ai légèrement modifié, et francisé.

Le script en question, qui doit être enregistré avec l’extension .ps1 (penser à modifier les variables de début de script) :

#################################################################################################################
#
# Version 1.4 February 2016
# Robert Pearman (WSSMB MVP)
# TitleRequired.com
# Script to Automated Email Reminders when Users Passwords due to Expire.
#
# Requires: Windows PowerShell Module for Active Directory
#
# For assistance and ideas, visit the TechNet Gallery Q&A Page. http://gallery.technet.microsoft.com/Password-Expiry-Email-177c3e27/view/Discussions#content
# Or Checkout my Youtube Channel - https://www.youtube.com/user/robtitlerequired
#
##################################################################################################################
# Please Configure the following variables....

$smtpServer="smtp.office365.com"
$expireindays = 14
$mailfrom = "expediteur@example.com"
$passwordFile = "D:\encrypted_password.txt"
$from = "Mot de passe <$mailfrom>"

$logging = "Enabled" # Set to Disabled to Disable Logging
$logFile = "C:\log_mail.csv" # ie. c:\mylog.csv

$testing = "Enabled" # Set to Disabled to Email Users
$testRecipient = "debug@example.com"

#
###################################################################################################################


# Force TLS1.2
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

# get password from file
$encryptedPassword = Get-Content $passwordFile | ConvertTo-SecureString
$Credential = New-Object System.Management.Automation.PsCredential($mailfrom, $encryptedPassword)

# Check Logging Settings
if (($logging) -eq "Enabled")
{
    # Test Log File Path
    $logfilePath = (Test-Path $logFile)
    if (($logFilePath) -ne "True")
    {
        # Create CSV File and Headers
        New-Item $logfile -ItemType File
        Add-Content $logfile "Date,Name,EmailAddress,DaystoExpire,ExpiresOn,Notified"
    }
} # End Logging Check

# System Settings
$textEncoding = [System.Text.Encoding]::UTF8
$date = Get-Date -format ddMMyyyy
# End System Settings

# Get Users From AD who are Enabled, Passwords Expire and are Not Currently Expired
Import-Module ActiveDirectory
$users = get-aduser -filter * -properties Name, PasswordNeverExpires, PasswordExpired, PasswordLastSet, EmailAddress |where {$_.Enabled -eq "True"} | where { $_.PasswordNeverExpires -eq $false } | where { $_.passwordexpired -eq $false }
$DefaultmaxPasswordAge = (Get-ADDefaultDomainPasswordPolicy).MaxPasswordAge

# Process Each User for Password Expiry
foreach ($user in $users)
{
    $Name = $user.Name
    $emailaddress = $user.emailaddress
    $passwordSetDate = $user.PasswordLastSet
    $PasswordPol = (Get-AduserResultantPasswordPolicy $user)
    $sent = "" # Reset Sent Flag
    # Check for Fine Grained Password
    if (($PasswordPol) -ne $null)
    {
        $maxPasswordAge = ($PasswordPol).MaxPasswordAge
    }
    else
    {
        # No FGP set to Domain Default
        $maxPasswordAge = $DefaultmaxPasswordAge
    }


    $expireson = $passwordsetdate + $maxPasswordAge
    $today = (get-date)
    $daystoexpire = (New-TimeSpan -Start $today -End $Expireson).Days

    # Set Greeting based on Number of Days to Expiry.

    # Check Number of Days to Expiry
    $messageDays = $daystoexpire

    if (($messageDays) -gt "1")
    {
        $messageDays = "dans " + "$daystoexpire" + " jours."
    }
    else
    {
        $messageDays = "aujourd'hui."
    }

    # Email Subject Set Here
    $subject="Votre mot de passe ESCDA expire $messageDays"

    # Email Body Set Here, Note You can use HTML, including Images.
    $body ="
    $name,
    <p> Votre mot de passe va expirer $messageDays<br>
    Pour changer votre mot de passe, appuyer sur Ctrl+Alt+Suppr et choisir Modifier un mot de passe <br>
    <p>Merci, <br>
    </P>"


    # If Testing Is Enabled - Email Administrator
    if (($testing) -eq "Enabled")
    {
        $emailaddress = $testRecipient
    } # End Testing

    # If a user has no email address listed
    if (($emailaddress) -eq $null)
    {
        $emailaddress = $testRecipient
    }# End No Valid Email

    # Send Email Message
    if (($daystoexpire -ge "0") -and ($daystoexpire -lt $expireindays))
    {
        $sent = "Yes"
        # If Logging is Enabled Log Details
        if (($logging) -eq "Enabled")
        {
            Add-Content $logfile "$date,$Name,$emailaddress,$daystoExpire,$expireson,$sent"
        }
        # Send Email Message
        Send-Mailmessage -Credential $Credential -smtpServer $smtpServer -from $from -to $emailaddress -Port "587" -useSsl -subject $subject -body $body -bodyasHTML -priority High -Encoding $textEncoding

    } # End Send Message
    else # Log Non Expiring Password
    {
        $sent = "No"
        # If Logging is Enabled Log Details
        if (($logging) -eq "Enabled")
        {
            Add-Content $logfile "$date,$Name,$emailaddress,$daystoExpire,$expireson,$sent"
        }
    }

} # End User Processing


# End

Ce script va parcourir les utilisateurs et isoler chaque utilisateur dont le mot de passe :

  • possède une date d’expiration
  • n’est pas encore expiré

et pour chacun d’eux, envoie un mail à l’adresse mail spécifiée dans leur profil AD, ou à l’adresse “$testRecipient” si aucune adresse n’est spécifiée.
(Note : en l’état, le script est en mode de test, et n’écrit donc qu’à l’adresse $testRecipient. pour activer l’envoi réel des mails aux utilisateurs, il faut passer $testing à Disabled dans les variables de début de script)

On retrouve la liste des utilisateurs traités (que leur adresse expire bientôt ou non) dans le fichier de log, par défaut C:\log_mail.csv. Ceci peut se désactiver en passant $logging à Disabled.

Tâche planifiée

Enfin, il faut activer l’éxécution automatique de ce script. Pour ceci, dans taskschd.msc, créer une tâche de base, mettre en programme/script powershell et en argument -windowstyle hidden -File "C:\chemin\vers\le\script\password_notification.ps1"

Lister les dates d’expiration de mot de passe

En powershell :
get-aduser -filter * -properties passwordlastset, passwordneverexpires |ft Name, passwordlastset, Passwordneverexpires

Source