PowerShell: Notificación por correo electrónico a los usuarios del tiempo restante hasta la caducidad de su contraseña de dominio

En esta entrada voy a explicaros como podemos notificar por correo electrónico a los usuarios, con una serie de días de antelación, de la caducidad de sus contraseñas de dominio.

Para ello simplemente tendréis que utilizar un script de PowerShell y configurar una tarea programada de Windows para que se ejecute de forma periódica.

Configuración Script

En primer lugar abriremos Windows PowerShell ISE o en su defecto cualquier editor de texto que tengamos.

A continuación vamos a ejecutar el siguiente comando para crear un fichero encriptado donde guardaremos la contraseña del buzón que utilizaremos para enviar el correo.

Importante: este fichero sólo podrá desencriptarlo el usuario que lo creó por lo que tenerlo en cuenta a la hora de la programación del script ya que debe ejecutarse con el mismo usuario que creó el fichero.

read-host -assecurestring | convertfrom-securestring | out-file C:\contrasena.txt

Una vez tenemos el fichero encriptado con la contraseña el siguiente paso será copiar el siguiente script y modificar la configuración para adaptarla a nuestro entorno.

#Dirección del servidor SMTP mediante el que enviaremos los correos electrónicos. En este ejemplo utilizo los servidores de Office 365.
$smtpServer="dirección smtp de nuestro correo"
#Dirección del remitente
$from = "remitente@dominio.com"
$pass = cat C:\contrasena.txt | convertto-securestring
$cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $from,$pass
$encoding=[System.Text.Encoding]::UTF8
#Mediante este parámetro filtraremos los usuarios a los que queremos realizar la notificación. Sólo se notificarán a los usuarios que les queden los días que hayamos definido en este parámetro. En este ejemplo 15 días o menos.
$expireindays = 15

Import-Module ActiveDirectory
#Obtenemos los usuarios a los que se notificará.
#En el ejemplo serán aquellos usuarios que se encuentren en la OU Internos de nuestro dominio, estén activos, no tengan marcado el check de que la contraseña nunca expira y la contraseña no haya expirado ya.
#Estos filtros podeis modificarlos para adaptarlos a vuestras necesidades
$users = get-aduser -filter {EmailAddress -like "*"} -SearchBase "ou=Internos,dc=dominio,dc=com" -properties * |where {$_.Enabled -eq "True"} | where { $_.PasswordNeverExpires -eq $false } | where { $_.passwordexpired -eq $false }

foreach ($user in $users)
{
  $Name = (Get-ADUser $user | foreach { $_.Name})
  $emailaddress = $user.emailaddress
  $passwordSetDate = (get-aduser $user -properties * | foreach { $_.PasswordLastSet })
  $maxPasswordAge = (Get-ADDefaultDomainPasswordPolicy).MaxPasswordAge
  $expireson = $passwordsetdate + $maxPasswordAge
  $today = (get-date)
  $daystoexpire = (New-TimeSpan -Start $today -End $Expireson).Days
  #En esta variable definiremos el asunto del correo
  $subject="Correo informativo: Caducidad de Contraseña en $daystoExpire días"
  #Mediante esta variable definiremos el cuerpo del correo que enviaremos.
  #El texto será en formato html por lo que podremos diseñarlo a nuestro gusto utilizando etiquetas de HTML
  $body ="
  <p>Le quedan $daystoexpire días para que su contraseña de acceso al dominio caduque. Por favor modifiquela a la mayor brevedad posible.</p>"

  if (($daystoexpire -lt $expireindays) -and ($daystoexpire -gt 0))
  {
    Send-Mailmessage -smtpServer $smtpServer -from $from -to $emailaddress -Credential $cred -subject $subject -body $body -bodyasHTML -priority High -Encoding $encoding     
  }    
}

Una vez hechas las modificaciones necesarias guardaremos el script en la ubicación que deseemos para utilizarlo en el siguiente paso.

Configuración tarea programada

Para que se ejecute el script crearemos una tarea programada en nuestro servidor controlador de dominio para en función de la periodicidad que definamos se envíen las notificaciones a los usuarios.

Es importante que esta tarea programada se ejecute con el mismo usuario que utilizamos para encriptar el fichero donde almacenamos la contraseña del buzón de correos utilizado para el envío de correos.

Para el ejemplo yo he creado una tarea que se ejecuta de forma diaria por las mañanas para informar a aquellos usuarios que le quedan 15 días o menos para la expiración de la contraseña.

Y listo con estos sencillos pasos los usuarios recibirán una notificación con suficiente antelación que les permita cambiar su contraseña de dominio a tiempo.

Espero os haya servido de utilidad.

18 comentarios en «PowerShell: Notificación por correo electrónico a los usuarios del tiempo restante hasta la caducidad de su contraseña de dominio»

  1. Gracias Sergio. Voy a tratar de implantarlo en mi AD, que usamos O365 y muchos ordenadores no estan unidos al dominio. Gran aporte.

    Responder
  2. Consulta,
    Para enviar un e-mail solamente a mi cuenta con toda la misma información, que linea del código debería modificar?
    gracias!

    Responder
    • Hola Federico,

      Para enviar un único correo con toda la información tendrías que modificar el script de tal forma que vayas guardando la información en la variable $body de forma concatenada, sacar del bucle la instrucción que envía el correo y ponerla fuera del bucle para que haga sólo el envío de un único correo con toda la información contenida en la variable $body.

      Saludos.

      Responder
  3. Buenas,
    me viene fenomenal este script, lo estoy intentando implementar pero no veo donde se configura la contraseña del servidor smtp ($from = «remitente@dominio.com»). Sin eso los correos no van a poder salir, si me puedes ayudar te estaría muy agradecido,

    un saludo,
    Jorge.

    Responder
    • Hola Jorge,

      He modificado la entrada para incluir la parte del login, revísala nuevamente para aplicar los cambios con los que creo se solucionará tu problema.

      Saludos.

      Responder
  4. Muy bueno, se podría hacer un log con la salida de cada ejecución?
    osea, los usuarios afectados en cada ejecución del script

    Responder
    • Hola Miguel,
      Para hacer lo que comentas deberías modificar el script e ir agregando la información que necesitas, por ejemplo, con la función Add-content
      Saludos.

      Responder
  5. Buenos días Sergio.

    Mi servidor Exchange identifica el mensaje como que viene de una organización externa cuando se trata de una cuenta de correo interna.

    ¿Hay alguna forma de configurarlo para que no lo trate como externo?

    Responder
    • Hola Daniel,

      Eso no es una configuración que se controle en el script sino que es algo que debes controlar a nivel de tu servidor de Exchange ya que el script lo único que hace es utilizar tu servidor de correos con la configuración que has establecido.

      Saludos.

      Responder
    • Hola Miguel,

      Comprueba que los datos de configuración que has puesto en el script son correctos o mira que no tengas ningún Firewall que esté bloqueando el puerto que utilizas para el envío de los correos.

      Responder
  6. Hola Sergio,

    Estoy intentando lanzar el script pero me da errores de STARTTLS, estoy utilizando los servidores de Office 365. ¿Sabes como podría solucionarlo?

    PD: Muchas gracias por el script y otras aportaciones, ya me ha ayudado un par de veces tu blog.

    Saludos!!

    Responder
    • Hola Alex,

      Prueba a la siguiente línea incluirle el puerto y el parámetro -UseSsl tal y como te pongo a continuación.

      Send-Mailmessage -smtpServer $smtpServer -from $from -to $emailaddress -Credential $cred -subject $subject -body $body -bodyasHTML -priority High -Encoding $encoding -Port 587 -UseSsl

      Saludos

      Responder
  7. Hola Sergio, de casualidad tienes un script para notificación de fecha de expiración de usuario, uno que notifique en un solo correo a un manager, ejemplo si 3 usuarios van a expirar y los 3 reportan al mismo manager que envié un solo correo y no 3 correos por cada usuario que va a expirar.

    Responder

Deja un comentario

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.