Yo, récemment, j’ai mis en place des comptes gMSA sur l’infrastructure pour renforcer la sécurité, et surtout, pour éliminer certains comptes de services dont le mot de passe n’expire jamais. Malheureusement, gMSA n’est pas compatible avec toutes les applications, et pour les rares comptes de service restants, j’ai désactivé l’option « Le mot de passe n’expire jamais ». Cela signifie que je dois maintenant surveiller la période d’expiration des mots de passe de ces comptes pour éviter toute interruption de service, et les changer tous les 180 jours.
Pour simplifier cette tâche, j’ai créé un script PowerShell dédié à la surveillance de ces comptes depuis Centreon. N’hésitez pas à l’adapter à vos besoins.
Le script peut checker 1 ou plusieurs compte à la fois
.\check_password_expiration.ps1 -account "user1,user2,user3" -warning 7 -critical 3
Il peut également checker par OU :
.\check_password_expiration.ps1 -searchbase "ou=Users,dc=example,dc=com" -warning 10 -critical 5
Il est possible de ne pas mettre les seuils. Par défaut c’est :
- Warning = mois de 10 jours avant expiration
- Critical = moins de 5 jours avant expiration
[int]$warning = 10, [int]$critical = 5,
Check Expiration Account
Pour vérifier par compte ou plusieurs
.\check_password_expiration.ps1 -account "xxxx,centreon,xxxxx,xxxxx,xxxxx,sysprep,xxxxx,xxxxx,test1" CRITICAL: xxxxx has password set to never expire. OK: centreon will expire in 180 days. OK: xxxxx will expire in 175 days. OK: xxxxx will expire in 179 days. CRITICAL: xxxxx will expire in 2 days. OK: sysprep will expire in 179 days. CRITICAL: xxxxx has password set to never expire. CRITICAL: xxxxx has password set to never expire. CRITICAL: xxxxx has password set to never expire. UNKNOWN: Account test1 not found.
Remarque :
J’ai masqué les noms…
Si le compte à la case « Le mot de passe n’expire jamais » cochée, il le remonte.
Si le compte n’existe pas, il le remonte
Il remonte les comptes qui ont déjà expiré.
Check Expiration par OU
Pour vérifier par OU :
.\check_password_expiration.ps1 -searchbase "ou=USERS,ou=SYSTEM,ou=ADMIN,dc=DOM,dc=LOCAL" CRITICAL: xxxxx will expire in 2 days. OK: xxxxx will expire in 62 days. WARNING: xxxxx will expire in 6 days. OK: xxxxx will expire in 57 days. CRITICAL: xxxxx is expired for 154468 days. CRITICAL: xxxxx is expired for 154468 days. OK: xxxxx will expire in 169 days. OK: xxxxx will expire in 22 days. CRITICAL: xxxxx has password set to never expire. OK: xxxxx will expire in 89 days. [...]
Remarque :
Bon, le but ce n’est pas de checker tout le monde.
Script PowerShell
Voici le script PowerShell :
<# .SYNOPSIS Script for checking Active Directory user password expiration. .DESCRIPTION This script checks the expiration status of passwords for Active Directory users. .AUTHOR asysadminstory.fr .VERSION 1.0 - Initial version: Check AD user password expiration. .PARAMETER searchbase Specifies the Organizational Unit (OU) to check for user password expiration. .PARAMETER account Specifies one or more user accounts to check for password expiration. .PARAMETER warning Sets the warning threshold for password expiration in days. .PARAMETER critical Sets the critical threshold for password expiration in days. .PARAMETER help Displays the script usage help. .EXAMPLE .\check_password_expiration.ps1 -searchbase "ou=Users,dc=example,dc=com" -warning 10 -critical 5 Checks password expiration for all users in the specified Organizational Unit. .EXAMPLE .\check_password_expiration.ps1 -account "user1,user2,user3" -warning 7 -critical 3 Checks password expiration for the specified user accounts. #> param ( [string]$searchbase, [string]$account, [int]$warning = 10, [int]$critical = 5, [switch]$help ) function Show-Help { Write-Host "Usage: Check-ADPasswordExpiration.ps1 -searchbase <OU> -account <account1,account2> [-warning <days>] [-critical <days>] [-help]" } function Get-PasswordExpiration { param ( [string]$samAccountName ) $user = Get-AdUser -Filter {SamAccountName -eq $samAccountName} -Properties "SamAccountName", "msDS-UserPasswordExpiryTimeComputed", "PasswordNeverExpires" if ($user) { # Vérifier si le mot de passe n'expire jamais if ($user.PasswordNeverExpires) { Write-Host "CRITICAL:", $($user.SamAccountName), "has password set to never expire." return 2 } $expirationDate = [datetime]::FromFileTime($user."msDS-UserPasswordExpiryTimeComputed") $daysRemaining = ($expirationDate - (Get-Date)).Days if ($daysRemaining -lt 0) { Write-Host "CRITICAL:",$($user.SamAccountName), "is expired for", $($daysRemaining * -1), "days." return 2 } elseif ($daysRemaining -lt $critical) { Write-Host "CRITICAL:",$($user.SamAccountName), "will expire in", $daysRemaining, "days." return 2 } elseif ($daysRemaining -lt $warning) { Write-Host "WARNING:",$($user.SamAccountName), "will expire in", $daysRemaining, "days." return 1 } else { Write-Host "OK:",$($user.SamAccountName), "will expire in", $daysRemaining, "days." return 0 } } else { Write-Host "UNKNOWN: Account ",$samAccountName, "not found." return 3 } } if ($help) { Show-Help exit 3 } if (($searchbase -and $account) -or (-not $searchbase -and -not $account)) { Write-Host "ERROR: Either --searchbase or --account is required, but not both." exit 3 } if ($account) { $accounts = $account -split "," $globalStatus = $null foreach ($acc in $accounts) { $status = Get-PasswordExpiration -samAccountName $acc.Trim() # Mettre à jour le statut global en cas de sortie critique ou inconnue if ($status -eq 2 -or $status -eq 3) { $globalStatus = $status } } # Sortie du statut global après avoir vérifié tous les comptes. if ($globalStatus -eq $null) { Write-Host "OK: All specified accounts are within expiration thresholds." exit 0 } else { exit $globalStatus } } elseif ($searchbase) { $users = Get-AdUser -Filter * -SearchBase $searchbase -Properties "SamAccountName", "msDS-UserPasswordExpiryTimeComputed", "PasswordNeverExpires" $globalStatus = $null foreach ($user in $users) { $status = Get-PasswordExpiration -samAccountName $user.SamAccountName # Mettre à jour le statut global en cas de sortie critique ou inconnue if ($status -eq 2 -or $status -eq 3) { $globalStatus = $status } } # Sortie du statut global après avoir vérifié tous les comptes. if ($globalStatus -eq $null) { Write-Host "OK: All accounts in the specified search base are within expiration thresholds." exit 0 } else { exit $globalStatus } } else { Write-Host "ERROR: Either --searchbase or --account is required." exit 3 }
Check via Centreon
Vous devez installer et configurer NSClient++ sur l’un de vos serveurs Active Directory. Mon fichier de conf NSClient se trouve ici : https://asysadminstory.fr/active-directory-dcdiag-avec-centreon-nsclient/
Il y a une version NSClient faite par Centreon intégrant les connecteurs de supervision.
- La doc est ici : centreon-nsclient-tutorial/
- Le lien (s’il n’est pas mort) : centreon nsclient 051 1.0 2 x64
J’ai mis le script PowerShell sur un serveur AD dans : C:\Scripts\check_password_expiration.ps1
Les commandes à mettre dans le fichier nsclient.ini
[/settings/external scripts/scripts] # Check by account check_account=cmd /c echo C:\Scripts\check_password_expiration.ps1 -account $ARG1$; exit $LastExitCode | powershell.exe -command - #Check by OU check_account_dn=cmd /c echo C:\Scripts\check_password_expiration.ps1 -searchbase $ARG1$; exit $LastExitCode | powershell.exe -command -
Se connecter à votre serveur Centreon et tester avec le plugin NSClient RestAPI:
[centreon-engine@centreon-central ~]$ /usr/lib/centreon/plugins/centreon_nsclient_restapi.pl --plugin=apps::nsclient::restapi::plugin --mode=query --hostname=IP_AD --port='8443' --proto='https' --legacy-password='InNSClient.ini' --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE" --timeout=30 --command=check_account --arg='"xxxx,centreon,xxxx,xxxx,xxxx,sysprep,xxxx,xxxx"' CRITICAL: xxxx has password set to never expire. OK: centreon will expire in 179 days. OK: xxxx will expire in 175 days. OK: xxxx will expire in 179 days. CRITICAL: xxxx will expire in 2 days. OK: sysprep will expire in 179 days. CRITICAL: xxxx has password set to never expire. CRITICAL: xxxx has password set to never expire. [centreon-engine@centreon-central ~]$
Vérifier les utilisateurs dans une OU
[centreon-engine@centreon-central ~]$ /usr/lib/centreon/plugins/centreon_nsclient_restapi.pl --plugin=apps::nsclient::restapi::plugin --mode=query --hostname=IP_AD --port='8443' --proto='https' --legacy-password='inNSClient.ini' --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE" --timeout=30 --command=check_account_dn --arg='"ou=USERS,ou=SYSTEME,ou=ADMIN,dc=DOM,dc=LOCAL"' CRITICAL: xxxxx will expire in 2 days. OK: xxxxx will expire in 62 days. WARNING: xxxxx will expire in 6 days. OK: xxxxx will expire in 57 days. CRITICAL: xxxxx is expired for 154468 days. CRITICAL: xxxxx is expired for 154468 days. OK: xxxxx will expire in 169 days. OK: xxxxx will expire in 22 days. CRITICAL: xxxxx has password set to never expire. OK: xxxxx will expire in 89 days. [...]
La commande pour Centreon WEB
- Nom : Windows-NSClient05-RestAPI
- Commande :
$CENTREONPLUGINS$/centreon_nsclient_restapi.pl --plugin=apps::nsclient::restapi::plugin --mode=query --hostname=$HOSTADDRESS$ --port='$_HOSTNSCPRESTAPIPORT$' --proto='$_HOSTNSCPRESTAPIPROTO$' --legacy-password='$_HOSTNSCPRESTAPILEGACYPASSWORD$' $_HOSTNSCPRESTAPIEXTRAOPTIONS$ --command=$_SERVICECOMMAND$ --arg=$_SERVICEARG1$
Configurer le service depuis l’interface web :
ARG1 = '"compte1,compte2,compte3"'
Répétez l’opération pour checker via une OU si vous le souhaitez.
Amusez vous bien. A très bientôt.
Bonne journée .