Desde Windows Vista, la advertencia de caducidad de contraseña es mucho menos agresiva que con XP.
Algunos usuarios que obvien esta viñeta recordatoria, o no suelan abrir sesion localmente (citrix, owa...) se encuentran con que la contraseña les ha expirado sin haberse dado cuenta.
Con este script powershell podemos avisar por mail de la caducidad de contraseñas con n dias de antelación a todos los usuarios.
Para mas información sobre los diferentes valores de este atributo: http://support.microsoft.com/kb/305144/en-us
Algunos usuarios que obvien esta viñeta recordatoria, o no suelan abrir sesion localmente (citrix, owa...) se encuentran con que la contraseña les ha expirado sin haberse dado cuenta.
Con este script powershell podemos avisar por mail de la caducidad de contraseñas con n dias de antelación a todos los usuarios.
Function Get-UAC($uac) { $flags=@() if ((65536 -band $uac) -ne "0"){$flags+="DONT_EXPIRE_PASSWORD"} return $flags } Function enviar-mail($mail,$body) { $subject="Aviso caducidad contraseña" $smtpServer = "SRVEXCH.DOMINIO.LOCAL" $emailFrom = "soporte@dominio.com" $smtp = new-object Net.Mail.SmtpClient($smtpServer,587) $mailAuthentication = new-object System.Net.NetworkCredential("mailcredentials", "password") $smtp.UseDefaultCredentials = $False $smtp.Credentials =$mailAuthentication $MailMessage = new-object Net.Mail.MailMessage($emailFrom, $mail, $subject, $body) $MailMessage.IsBodyHtml = $true $smtp.Send($MailMessage) } ##### main ##### out-file "mailing_caducidad_contraseñas.csv" -input "usuario;ultimocambio;fechacaducidad;dias;avisado" $SECS_IN_A_DAY=86400 $domain = [ADSI]"WinNT://$env:userdomain" $intMaxPwdAge =($domain.maxpasswordage.value)/$SECS_IN_A_DAY $ahora=get-date #lista los datos de todos los usuarios del dominio $searcher = New-Object DirectoryServices.DirectorySearcher([adsi]"") $searcher.filter = "(&(objectclass=user)(objectcategory=person)(mail=*)(!userAccountControl:1.2.840.113556.1.4.803:=2))" $users = $searcher.findall() Foreach($user in $users) { $TheUser=$user.GetDirectoryEntry() $usuario=$theuser.samaccountname $nombre=$theuser.givenname $apellidos=$theuser.sn $mail=$theuser.mail $uac=$theUser.userAccountControl $flags=Get-Uac("$uac") if ($flags -notcontains "DONT_EXPIRE_PASSWORD") { $PasswordLastChanged =$theuser.PasswordLastChanged $intTimeInterval = [int32]($ahora - $PasswordLastChanged).days If ($intTimeInterval -ge $intMaxPwdAge) { $strExpiringDays="CADUCADA" $avisar=0 } else { $ExpiringDate = $PasswordLastChanged.addDays($intMaxPwdAge) $fechacaducidad=$Expiringdate.toString("dd/MM/yyyy") $ExpiringDays = [int32]($ExpiringDate - $ahora).days $strExpiringDays= "$ExpiringDays dias" #Avisar con 7 dias de antelacion if ($ExpiringDays -le 7) { $avisar=1 $body= "$nombre $apellidos, usuario del sistema $usuario. Tu contraseña va a caducar dentro de " + $ExpiringDays + " días (" + $fechacaducidad + "). Puedes cambiarla conectándote al correo OWA. Si no lo haces, tu cuenta se bloqueará y deberás abrir incidencia en 'soporte' para que la vuelvan a habilitar. Soporte Sistemas" enviar-mail $mail $body } else { $avisar=0 }#fin de if 7 dias }#fin de if caducada write-host "$usuario - $PasswordLastChanged - $strExpiringDays ($avisar)" -fore cyan out-file ".\mailing_caducidad_contraseñas.csv" -input "$usuario;$PasswordLastChanged;$fechacaducidad;$strExpiringDays;$avisar" -append }#fin de flags uac validos }#fin foreachEl atributo userAccountControl es el encargado de almacenar las opciones de cuenta de usuario: ACCOUNTDISABLE, DONT_EXPIRE_PASSWORD, SMARTCARD_REQUIRED, PASSWD_NOTREQD... asignando valores decimales acumulativos a cada opción.
Para mas información sobre los diferentes valores de este atributo: http://support.microsoft.com/kb/305144/en-us
Hola, tengo un escenario con windows 2008 R2 y lotus como servidor de correo. Este scrip no me sirve, no?
ResponderEliminarYa lo probe y funciona correctamente dentro de mi escenario, solo hay que cambiar el valor de $smtpServer.
ResponderEliminarColocando la ip del servidor de correo funciono correctamente.
Este comentario ha sido eliminado por el autor.
ResponderEliminarBuenos Tardes,
ResponderEliminarMe gustaría avisar a los usuarios por mail de la caducidad de sus contraseñas, donde debería poner este script.
Como podría hacer la prueba para ver si funciona.
Gracias
crea una tarea programada en cualquier servidor miembro y ejecuta el script powershell.
Eliminaro bien ejecutas powershell.exe y pasas como parametro la ruta del script o haz un bat que invoca al script y ejecuta el bat en la tarea programada.
Para que envie los correos tendras que corregir el servidor de correo en la linea 10 del script
Buenas Tardes. ¿ Se podría hacer lo mismo pero que es su certificado digital lo que se le va a acabar ? Un saludo y gracias.
ResponderEliminarclaro, una fecha es una fecha, da igual que queden 7 dias para que expire una contraseña o que caduque un certificado. podrias reutilizar la mayor parte del script del articulo
EliminarTengo varios errores al ejecutar este script, me podría ayudar a validar que puede estar sucediendo??? Muchas gracias.
ResponderEliminarCannot convert value to type System.String.
At line:73 char:2
+ out-file "C:\Bats\mailing_caducidad_contraseñas_07032023.csv" -input ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvalidCastFromAnyTypeToString
Este error también se presenta...
ResponderEliminarCannot convert value to type System.String.
At line:72 char:2
+ write-host "$usuario - $PasswordLastChanged - $strExpiringDays ($avi ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvalidCastFromAnyTypeToString
Exception calling "Send" with "1" argument(s): "Failure sending mail."
ResponderEliminarAt line:18 char:1
+ $smtp.Send($MailMessage)
+ ~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : SmtpException
Method invocation failed because [System.Management.Automation.PSMethod] does not contain a method named 'addDays'.
ResponderEliminarAt line:52 char:3
+ $ExpiringDate = $PasswordLastChanged.addDays($intMaxPwdAge)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : MethodNotFound
Cannot find an overload for "op_Subtraction" and the argument count: "2".
ResponderEliminarAt line:44 char:2
+ $intTimeInterval = [int32]($ahora - $PasswordLastChanged).days
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodException
+ FullyQualifiedErrorId : MethodCountCouldNotFindBest
Súper script. Tremenda ayuda. Bendiciones!!
ResponderEliminarbuenas, consulta hay un parametro para definir sobre que OUs impacte como para determinar un grupo de usuarios?
ResponderEliminarSi, ponlo en $searcher = New-Object DirectoryServices.DirectorySearcher([adsi]"")
Eliminarpor ejemplo $searcher = New-Object DirectoryServices.DirectorySearcher([adsi]"LDAP://OU=aqui,DC=dominio,DC=int")