El Blog de Gualtrysoft

Windows 2000/2003/2008, Active Directory, VBScript, Hyper-V, PowerShell y todo aquello interesante a la hora de usar, configurar y administrar Windows Server. También tenemos longanizas…

Script VBScript Para Listar La Caducidad De Las Contraseñas De Los Usuarios De Un Dominio De Active Directory

Posted by urpiano en Miércoles 5 \05\UTC marzo \05\UTC 2008

Este script nos permite listar la fecha en la que caduca las contraseñas de todos los usuarios del dominio que se recibe como parámetro. El script permite volcar los resultados en un fichero o mostrarlos por pantalla.

Sintaxis

cscript [//nologo] listar-caducidad-password-ad.vbs [/F:fichero] [/?] dominio

Siendo

Etiqueta Dato ¿Requerido? Descripción
  dominio
Nombre FQDN del dominio en el que se consulta
F fichero No
Ruta y nombre del fichero de valores separados por tabuladores (ideal para abrir con Excel) en el que se volcarán los resultados; si se omite, la información se muestra por pantalla
?   No
Muestra la ayuda en línea.

Ejemplos:

– Muestra la caducidad de las contraseñas de los usuarios del dominio “tia.org”:

cscript //nologo listar-caducidad-password-ad.vbs tia.org

– Muestra la caducidad de las contraseñas de los usuarios del dominio “tia.org” y guarda la información en el archivo de valores separados por comas “c:listados adcaducidad.tsv”:

cscript //nologo listar-caducidad-password-ad.vbs /F:"c:listados adcaducidad.tsv" tia.org

Este es el código del script

'*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*
'*°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°*
'* listar-caducidad-password-ad.vbs                                    *
'*                                                                     *
'* Este script nos permite listar la fecha en la que caduca las        *
'* contraseñas de todos los usuarios del dominio que se recibe como    *
'* parámetro. El script permite volcar los resultados en un fichero o  *
'* mostrarlos por pantalla.                                            *
'*                                                                     *
'* Sintaxis                                                            *
'*                                                                     *
'* cscript [//nologo] listar-caducidad-password-ad.vbs [/F:fichero]    *
'* [/?] dominio                                                        *
'*                                                                     *
'* Siendo                                                              *
'*                                                                     *
'* - dominio (Requerido):                                              *
'*         Nombre FQDN del dominio en el que se consulta               *
'*                                                                     *
'* - /F: fichero (Opcional):                                           *
'*         Ruta y nombre del fichero de valores separados por          *
'*         tabuladores (ideal para abrir con Excel) en el que se       *
'*         volcarán los resultados; si se omite, la información se     *
'*         muestra por pantalla                                        *
'*                                                                     *
'* - /?: ayuda (Opcional):                                             *
'*         Muestra la ayuda en línea                                   *
'*                                                                     *
'*                                                                     *
'* Ejemplos:                                                           *
'*                                                                     *
'* - Muestra la caducidad de las contraseñas de los usuarios del       *
'* dominio "tia.org":                                                  *
'*                                                                     *
'* cscript //nologo listar-caducidad-password-ad.vbs tia.org           *
'*                                                                     *
'* - Muestra la caducidad de las contraseñas de los usuarios del       *
'* dominio "tia.org" y guarda la información en el archivo de valores  *
'* separados por comas "c:listados adcaducidad.tsv":                 *
'*                                                                     *
'* cscript //nologo listar-caducidad-password-ad.vbs /F:"c:listados   *
'* adcaducidad.tsv" tia.org                                           *
'*                                                                     *
'*                                                                     *
'*                                                                     *
'*                                                                     *
'* © Fernando Reyes                                                    *
'* Marzo De 2008                                                       *
'*°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°*
'*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*

'Exigimos la declaración de variables
Option Explicit

Const SEGUNDOS_POR_DIA = 86400
Const ADS_UF_DONT_EXPIRE_PASSWD = &h10000
Const ADS_UF_ACCOUNTDISABLE = 2

Dim str_Error     'As String
Dim int_Error     'As String
Dim str_Dominio   'As String
Dim str_DominioNT 'As String
Dim str_Fichero   'As String
Dim str_Salida    'As String

Dim obj_FS        'As Scripting.FileSystemObject
Dim obj_TS        'As Scripting.TextStream

Dim ado_Conexion  'As ADODB.Connection
Dim ado_Comando   'As ADODB.Command
Dim rs_Usuarios   'As ADODB.Recordset

Dim obj_Dominio
Dim int_DiasCaducidad

'Validando los argumentos y almacenando
'sus valores
If f_RevisarArgumentos( _
                       str_Error, _
                       int_Error) Then

    Call s_Ayuda(str_Error)
    WScript.Quit int_Error

End If

'Obtenemos los dias de caducidad para las contraseñas
'en el dominio
Set obj_Dominio = GetObject("WinNT://" & str_DominioNT)
int_DiasCaducidad = obj_Dominio.Get("MaxPasswordAge")
int_DiasCaducidad = (int_DiasCaducidad/SEGUNDOS_POR_DIA)
Set obj_Dominio = Nothing

'Obtenemos los usuarios del dominio
'Para ello consultaremos por medio de ADO a ADSI
'Creamos un objeto conexión de ADO
Set ado_Conexion = CreateObject("ADODB.Connection")

'Establecemos el proveedor ADSI para la conexión
ado_Conexion.Open "Provider=ADsDSOObject;"

'Creamos un objeto comando de ADO
Set ado_Comando = CreateObject("ADODB.Command")

'Establecemos que su conexión es la anteriormente creada
ado_Comando.ActiveConnection = ado_Conexion

'Establecemos propiedades de acceso a los datos
'para evitar el límite de 1000 resultados que
'tiene ADSI de forma predeterminada.
ado_Comando.Properties("Page Size") = 100
ado_Comando.Properties("Timeout") = 30
ado_Comando.Properties("Cache Results") = False

'Establecemos la cadena de consulta
ado_Comando.CommandText = _
    "<GC://" & str_Dominio & ">;(objectCategory=User)" & _
        ";distinguishedName;subtree"

'Creamos el Recordset con los nombres distinguidos de los
'usuarios
Set rs_Usuarios = ado_Comando.Execute

'Ponemos los encabezados en función de si hay que guardar
'los resultados en un fichero o no. Primero si hay que
'guardarlos
If Len(str_Fichero) > 0 Then

    str_Salida = "Nombre Usuario" & vbTab & _
                 "Nombre Distinguido" & vbTab & _
                 "¿Tiene Caducidad?" & vbTab & _
                 "Dia Último Cambio" & vbTab & _
                 "Hora Último Cambio" & vbTab & _
                 "Dias Desde Cambio" & vbTab & _
                 "Máxima Edad Permitida" & vbTab & _
                 "Caduca El" & vbTab & _
                 "Dias Hasta Caducar" & vbTab & _
                 "¿Caducada?" & vbTab & _
                 "¿Cuenta Deshabilitada?" & vbCrLf

'Sólo se muestran por pantalla. Para evitar que en CMD
'se rompa la tabla por falta de ancho, reducimos los datos
'a mostrar, dejando sólo el nombre de usuario, si tiene
'caducidad, la fecha en que cambió por última vez la
'contraseña, la fecha en que caduca, los días que faltan
'hasta que caduque, si está caducada y si está deshabilitada
Else

    str_Salida = "Nombre Usuario" & vbTab & _
                 "¿Caduca?" & vbTab & _
                 "Dia Cambio" & vbTab & _
                 "Caduca El" & vbTab & _
                 "Dias Caducará" & vbTab & _
                 "¿Caducada?" & vbTab & _
                 "¿Deshabilitada?"

    'Mostramos los encabezados
    WScript.Echo str_Salida

    'Subrayamos los encabezados
    str_Salida = String(14,"=") & vbTab & _
                 String(8,"=") & vbTab & _
                 String(10,"=") & vbTab & _
                 String(9,"=") & vbTab & _
                 String(13,"=") & vbTab & _
                 String(10,"=") & vbTab & _
                 String(15,"=")

    'Mostramos los subrayados
    WScript.Echo str_Salida

    'Vaciamos la variable de salida
    str_Salida = ""

End If

'Recorremos el Recordset
While Not rs_Usuarios.EOF

    'Llamamos al procedimiento que procesa el usuario
    Call s_ProcesaUsuario(rs_Usuarios.Fields( _
                                    "distinguishedName"))

    'Vamos al siguiente usuario
    rs_Usuarios.MoveNext

Wend

'Cerramos el Recordset
rs_Usuarios.Close

'Vaciamos su variable
Set rs_Usuarios = Nothing

'Vaciamos la variable del objeto comando ADO
Set ado_Comando = Nothing

'Cerramos la conexión
ado_Conexion.Close

'Vaciamos la variable del objeto conexión ADO
Set ado_Conexion = Nothing

'Si hay que volcar información en el fichero
'de salida de ruta y nombre str_Fichero
If Len(str_Fichero) > 0 Then

    'Creamos un objeto FileSystemObject
    Set obj_FS = CreateObject("Scripting.FileSystemObject")

    'Creamos el fichero de salida
    Set obj_TS = obj_FS.CreateTextFile(str_Fichero)

    'Volcamos la información de salida en el fichero
    obj_TS.Write str_Salida

    'Cerramos el fichero de salida
    obj_TS.Close

    'Limpieza de popa :-)
    Set obj_TS = Nothing
    Set obj_FS = Nothing

End If

Sub s_ProcesaUsuario(str_Usuario)
'***********************************************************************
'* Procedimiento: s_ProcesaUsuario                                     *
'* Tipo         : Método                                               *
'* Devolución   : Ninguna                                              *
'* Fecha y Hora : 05/03/2008 17:19:03                                  *
'* Autor        : Fernando Reyes                                       *
'*¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯*
'* Propósito    : Este método recibe un nombre LDAP de usuario, lo     *
'*                obtiene de Active Directory, revisa la caducidad de  *
'*                su contraseña y muestra por pantalla o vuelca a      *
'*                fichero los datos                                    *
'***********************************************************************

    Dim obj_Usuario         'As Object
    Dim int_ControlDeCuenta 'As Integer
    Dim dth_UltimoCambio    'As DateTime
    Dim int_DiasEstablecida 'As Integer
    Dim str_Datos           'As String

    'Creamos un objeto iADsUser con el usuario recibido como parámetro
    Set obj_Usuario = GetObject("LDAP://" & str_Usuario)

    'Establecemos control de errores
    On Error Resume Next

    'Obtenemos el control de cuenta del usuario
    int_ControlDeCuenta = obj_Usuario.Get("userAccountControl")

    'Si se ha producido un error salimos del procedimiento
    If Err.Number <> 0 Then

        'Vaciamos la variable del usuario
        Set obj_Usuario = Nothing

        'Ponemos a cero el objeto Err
        Err.Clear

        'Salimos del procedimiento
        Exit Sub

    End If

    'Devolvemos el control de errores a cscript
    On Error Goto 0

    'Si la contraseña no caduca
    If (int_ControlDeCuenta and ADS_UF_DONT_EXPIRE_PASSWD) _
    Or int_DiasCaducidad < 0 Then

        'Almacenamos que no caduca, ponemos a cero los valores
        'de fechas y días, ponemos que no ha caducado y ponemos
        'si está o no deshabilitada. El nombre distinguido sólo
        'se devuelve si se guarda la información en un fichero
        str_Datos = Replace(obj_Usuario.Name,"cn=","",1,-1,1) & _
                                                        vbTab & _
                    f_IIf(Len(str_Fichero)>0, _
                              str_Usuario & vbTab, _
                              "") & _
                    False & vbTab & _
                    f_IIf(Len(str_Fichero)>0, _
                          0 & vbTab, _
                          "") & _
                    f_IIf(Len(str_Fichero)>0, _
                          0 & vbTab, _
                          "") & _
                    f_IIf(Len(str_Fichero)>0, _
                          0 & vbTab, _
                          "") & _
                    0 & vbTab & _
                    0 & vbTab & _
                    0 & vbTab & _
                    False & vbTab & _
                    ((int_ControlDeCuenta _
                      And ADS_UF_ACCOUNTDISABLE) = _
                          ADS_UF_ACCOUNTDISABLE)

    'La contraseña caduca
    Else

        'Establecemos control de errores
        On Error Resume Next

        'Obtenemos la fecha en la que cambó la contraseña el
        'usuario por última vez
        dth_UltimoCambio = obj_Usuario.PasswordLastChanged 

        'Si se ha producido un error
        If Err.Number <> 0 Then

            'Que haya un error significa que el usuario nunca
            'ha cambiado su contraseña. Esto es motivado cuando
            'el usuario es de reciente creación y nunca tuvo
            'que cambiar su contraseña, o con usuario plantilla
            'que se crean y nunca se usan para logarse, con lo que
            'nunca se les cambia la contraseña. En ambos casos,
            'como fecha último cambio de contraseña, almacenamos
            'la fecha de creación del usuario
            dth_UltimoCambio = obj_Usuario.Get("whenCreated")

            'Ponemos a cero el objeto Err
            Err.Clear

        End If

        'Devolvemos el control de errores a cscript
        On Error Goto 0

        'Obtenemos el número de días que la contraseña
        'lleva activa, esto es, el día de hoy menos la fecha
        'de último cambio
        int_DiasEstablecida = Int(Now - dth_UltimoCambio)

        'Almacenamos los datos:
        '           1.- Nombre de usuario
        '           2.- Nombre distinguido de usuario (si se
        '               está volcando el resultado a un fichero)
        '           3.- Si la contraseña tiene caducidad
        '           4.- Fecha de última modificación
        '           5.- Hora de última modificación (si se
        '               está volcando el resultado a un fichero)
        '           6.- Dias que lleva establecida (si se
        '               está volcando el resultado a un fichero)
        '           7.- Dias de máxima duración de una contraseña
        '               (si se está volcando el resultado a un
        '               fichero)
        '           8.- Fecha en la que caduca
        '           9.- Días que faltan para caducar (0 o negativo
        '               para las contraseña que están caducadas)
        str_Datos = Replace(obj_Usuario.Name,"cn=","",1,-1,1) & _
                                                        vbTab & _
                    f_IIf(Len(str_Fichero)>0, _
                          str_Usuario & vbTab, _
                          "") & _
                    True & vbTab & _
                    DateValue(dth_UltimoCambio) & vbTab & _
                    f_IIf(Len(str_Fichero)>0, _
                          TimeValue(dth_UltimoCambio) & vbTab, _
                              "") & _
                    f_IIf(Len(str_Fichero)>0, _
                          int_DiasEstablecida & vbTab, _
                          "") & _
                    f_IIf(Len(str_Fichero)>0, _
                          int_DiasCaducidad & vbTab, _
                          "") & _
                    DateValue(dth_UltimoCambio + _
                                   int_DiasCaducidad) & vbTab & _
                    Int((dth_UltimoCambio + _
                            int_DiasCaducidad) - Now) & vbTab

        'Añadimos, si la contraseña está o no caducada y si está
        'o no deshabilitada
        str_Datos = str_Datos & _
                    (int_DiasEstablecida >= int_DiasCaducidad) & _
                    vbTab & _
                    ((int_ControlDeCuenta _
                      And ADS_UF_ACCOUNTDISABLE) = _
                          ADS_UF_ACCOUNTDISABLE)

    End If

    'Si hemos obtenido datos
    If Len(Trim(str_Datos)) > 0 Then

        'Pasamos los datos a la variable de salida
        str_Salida = str_Salida & str_Datos

        'Si hay que guardar la información en un fichero...
        If Len(str_Fichero) > 0 Then

            'Añadimos un salto de línea preparando el siguiente
            'usuario
            str_Salida = str_Salida & vbCrLf   

        'Sólo se muestran por pantalla
        Else

            'Mostramos la salida por pantalla
            WScript.Echo str_Salida

            'Vaciamos la variable de salida
            str_Salida = ""

        End If

    End If 

    'Limpieza de pompis :-)
    Set obj_Usuario = Nothing

End Sub 's_ProcesaUsuario

Function f_RevisarArgumentos( _
                             str_Error, _
                             int_Error _
                             ) 'As Boolean
'***********************************************************************
'* Procedimiento: f_RevisarArgumentos                                  *
'* Tipo         : Función                                              *
'* Devolución   : Booleana                                             *
'* Fecha y Hora : 05/03/2008 16:55:23                                  *
'* Autor        : Fernando Reyes                                       *
'*¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯*
'* Propósito    : Esta función revisa los argumentos recibidos,        *
'*                recogiendo los posibles fallos por falta de          *
'*                argumentos requeridos y almacenando en las           *
'*                variables correspondientes los argumentos            *
'*                recibidos. recibe dos parámetros cuyo fin es ser de  *
'*                salida: una cadena que almacenará los errores        *
'*                detectados y un entero que almacenará el código de   *
'*                los errores detectados. Hay tres tipos de error;     *
'*                error 1 para los argumentos sin nombre requeridos y  *
'*                no encontrados, error 2 para los argumentos con      *
'*                nombre requeridos y no encontrados, por último,      *
'*                error 4 para los combos de argumentos opcionales     *
'*                (un combo de argumentos opcionales es aquel          *
'*                conjunto de argumentos opcionales que es requerido   *
'*                que se pase al menos uno de ellos y que si se pasa   *
'*                más de uno se ignorarán aquellos que estén detrás    *
'*                en la prioridad entre ellos; una característica      *
'*                clara de lo que es un combo de argumentos es cuando  *
'*                dos omás argumentos almacenan su valor en la misma   *
'*                variable). En el caso de producirse más de un tipo   *
'*                de error, el número de error será la suma de ambos   *
'*                de los errores recibidos, es decir 3, 5 o 6          *
'***********************************************************************

    Dim bol_Devolucion 'As Boolean
    Dim bol_Error1 'As Boolean
    Dim bol_Error2 'As Boolean
    Dim bol_Error4 'As Boolean

    'Iniciamos los indicadores
    bol_Devolucion = False
    bol_Error1 = False
    bol_Error2 = False
    bol_Error4 = False

    'Si hay que mostrar la ayuda, se muestra y
    'termina el script
    If WScript.Arguments.Named.Exists("?") Then

        Call s_Ayuda("******************" & vbCrLf & _
                     "*     AYUDA      *" & vbCrLf & _
                     "******************")

        WScript.Quit 0

    End If

    'Revisamos si están todos los argumentos
    'sin nombre requeridos
    If WScript.Arguments.Unnamed.Count < 1 Then

        str_Error = "Error 1, falta/n argumento/s sin " & _
                    "nombre requerido/s"
        bol_Error1 = True

    Else

        'Guardamos los argumentos en las variables
        'correspondientes
        str_Dominio = WScript.Arguments.Unnamed(0)

        'Pasamos el nombre FQDN del dominio a nombre
        'LDAP
        str_Dominio = "dc=" & _
                      Replace(str_Dominio, _
                              ".", _
                              ",dc=")

        'Obtenemos ahora el nombre NT del dominio
        str_DominioNT = Replace(f_NTaDN("", str_Dominio),"","")

    End If

    'Revisamos que esté el argumento
    '/F (fichero)
    If WScript.Arguments.Named.Exists("F") Then

        str_Fichero =  _
               WScript.Arguments.Named("F")

    End If

    'Preparamos las variables de devolucion:
    'el entero como suma de los posibles errores 1, 2 y 4
    int_Error = Abs(bol_Error1) + _
                (2 * Abs(bol_Error2)) + _
                (4 * Abs(bol_Error4))
    'La devolucion de la función será True en caso de
    'haber alguno de los errores
    bol_Devolucion = (bol_Error1 Or bol_Error2 Or bol_Error4)

    'Hacemos la devolución de la función
    f_RevisarArgumentos = bol_Devolucion

End Function 'f_RevisarArgumentos

Sub s_Ayuda(str_Error)
'***********************************************************************
'* Procedimiento: s_Ayuda                                              *
'* Tipo         : Sub                                                  *
'* Devolución   :                                                      *
'* Fecha y Hora : 05/03/2008 16:55:23                                  *
'* Autor        : Fernando Reyes                                       *
'*¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯*
'* Propósito    : Este procedimiento muestra la ayuda en línea.        *
'*                Recibe un parámetro de tipo cadena que si viene      *
'*                será mostrado antes de la línea; pensado para que    *
'*                se muestre un error que se haya detectado.           *
'***********************************************************************

    'Si hay que mostrar algún texto previo a la ayuda, lo hacemos
    If Len(str_Error) > 0 Then

        WScript.Echo str_Error & vbCrLf & vbCrLf

    End If

    'A continuación, mostramos la ayuda por pantalla
    WScript.Echo "Este script nos permite listar la fecha en la que" & _
                 " caduca las contraseñas de"
    WScript.Echo "todos los usuarios del dominio que se recibe como" & _
                 " parámetro. El script permite"
    WScript.Echo "volcar los resultados en un fichero o mostrarlos " & _
                 "por pantalla."
    WScript.Echo ""
    WScript.Echo "Sintaxis"
    WScript.Echo ""
    WScript.Echo "cscript [//nologo] listar-caducidad-password-ad.v" & _
                 "bs [/F:fichero] [/?] dominio"
    WScript.Echo ""
    WScript.Echo "Siendo"
    WScript.Echo ""
    WScript.Echo "- dominio (Requerido):"
    WScript.Echo "Nombre FQDN del dominio en el que se consulta"
    WScript.Echo ""
    WScript.Echo "- /F: fichero (Opcional):"
    WScript.Echo "Ruta y nombre del fichero de valores separados po" & _
                 "r tabuladores"
    WScript.Echo "(ideal para abrir con Excel) en el que se volcará" & _
                 "n los resultados; si se omite, la información se " & _
                 "muestra por pantalla"
    WScript.Echo ""
    WScript.Echo "- /?: ayuda (Opcional):"
    WScript.Echo "Muestra la ayuda en línea"
    WScript.Echo ""
    WScript.Echo ""
    WScript.Echo "Ejemplos:"
    WScript.Echo ""
    WScript.Echo "- Muestra la caducidad de las contraseñas de los " & _
                 "usuarios del dominio ""tia.org"":"
    WScript.Echo ""
    WScript.Echo "cscript //nologo listar-caducidad-password-ad.vbs" & _
                 " tia.org"
    WScript.Echo ""
    WScript.Echo "- Muestra la caducidad de las contraseñas de los " & _
                 "usuarios del dominio tia.org"
    WScript.Echo "y guarda la información en el archivo de valores " & _
                 "separados por comas"
    WScript.Echo """c:listados adcaducidad.tsv"":"
    WScript.Echo ""
    WScript.Echo "cscript //nologo listar-caducidad-password-ad.vbs" & _
                 " /F:""c:listados adcaducidad.tsv"" tia.org"
    WScript.Echo ""
    WScript.Echo ""
    WScript.Echo ""

End Sub 's_Ayuda

Function f_NTaDN(str_RutaNT, str_DN)
'***********************************************************************
'* Procedimiento: f_NTaDN                                              *
'* Tipo         : Función                                              *
'* Devolución   : Cadena                                               *
'* Fecha y Hora : May 2007                                             *
'* Autor        : Fernando Reyes                                       *
'*¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯*
'* Propósito    : Esta función recibe o bien el nombre NT              *
'*                ("dominionombre"), como primer parámetro, de un     *
'*                objeto de dominio y devuelve el nombre distinguido   *
'*                de ese objeto, o bien el nombre distinguido de un    *
'*                objeto, como segundo parámetro, y devuelve el        *
'*                nombre NT.                                           *
'*                Basada en el código de Richard Mueller, MVP de       *
'*                Scripting y ADSI (http://www.rlmueller.net)          *
'***********************************************************************

    'Constantes para el objeto NameTranslate
    Const ADS_NAME_INITTYPE_GC = 3
    Const ADS_NAME_TYPE_NT4 = 3
    Const ADS_NAME_TYPE_1779 = 1

    Dim obj_TraductorDeNombres
    Dim int_De, int_A,str_Nombre

    If  Len(str_RutaNT) > 0 Then

        int_De = ADS_NAME_TYPE_NT4
        int_A = ADS_NAME_TYPE_1779
        str_Nombre = str_RutaNT

    ElseIf Len(str_DN) > 0 Then

        int_De = ADS_NAME_TYPE_1779
        int_A = ADS_NAME_TYPE_NT4
        str_Nombre = str_DN

    Else

        WScript.Echo "Error 1 en f_NTaDN: No se ha pasado " & _
                     "ningún nombre para traducir."
        Exit Function
    End If
    'Creamos el objeto NameTranslate.
    Set obj_TraductorDeNombres = CreateObject("NameTranslate")

    On Error Resume Next

    'Lo iniciamos localizando el catálogo global
    obj_TraductorDeNombres.Init ADS_NAME_INITTYPE_GC, ""

    'Establecemos el parámetro de nombre en el traductor de nombres
    obj_TraductorDeNombres.Set int_De, str_Nombre

    'Usamos el método Get del traductor de nombres para obtener el
    'nombre traducido
    f_NTaDN = obj_TraductorDeNombres.Get(int_A)

    'Si se hubiese pasado un nombre LDAP de dominio ,el nombre de
    'NT de dominio obtenido termina en backslash (), cosa que
    'estorba, lo quitamos
    If Right(f_NTaDN, 1) = "" Then _
        f_NTaDN = Left(f_NTaDN, Len(f_NTaDN) -1)

    'Limpieza de kks :-)
    Set obj_TraductorDeNombres = Nothing

    On Error GoTo 0

End Function 'f_NTaDN

Function f_IIf(bol_Expresion, _
               var_Verdadero, _
               var_Falso)
'***********************************************************************
'* Procedimiento: f_IIf                                                *
'* Tipo         : Función                                              *
'* Devolución   : Variant                                              *
'* Fecha y Hora : Julio de 2007                                        *
'* Autor        : Fernando Reyes                                       *
'*¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯*
'* Propósito    : Esta función emula la función Iif de VBA.Recibe una  *
'*                booleana, que será el resultado de una expresión     *
'*                que se ponga como parámetro al llamar la función,    *
'*                tal y como se hace en la función IIf de VBA, y       *
'*                devolverá lo que se pase como parámetro              *
'*                var_Verdadero, si la booleana es verdadera o lo que  *
'*                se pase como parámetro var_Falso si la booleana es   *
'*                falsa.                                               *
'***********************************************************************

    if bol_Expresion Then

        f_IIF = var_Verdadero

    Else

        f_IIf = var_Falso

    End If

End Function 'f_IIf

 

 

22 comentarios to “Script VBScript Para Listar La Caducidad De Las Contraseñas De Los Usuarios De Un Dominio De Active Directory”

  1. Mav said

    Buenas tardes,

    No sabia donde poner esta pregunta y te la pongo aqui. Te cuento, tenemos que instalar un certificado *.pfx el cual contiene la clave privada y publica, bien, queremos hacerlo de forma desatendida y no he conseguido ver la forma.

    Me gustaría saber si se puede hacer mediante VBSCript y como, ya que en estos temas nos perdemos bastante, ya que es muy nuevo para nosotros. Nos gustaria que el Script instalara el certificado de forma automatica, proporcionandole la clave en el script sin que pida ningún dato al usuario. ¿Es posible?

    Muchas gracias de antemano y un saludo

  2. Hermenegildo said

    May,

    Eso lo puedes intentar con el objeto wshShell y su método SendKey:

    VBScript SendKeys Function
    Guy’s Scripting Ezine 120 – SendKeys
    VBScript Sendkeys Shortcuts
    Método SendKeys
    SendKeys Method

  3. Jose Ramon Pernia Reyes said

    Cuando intento ejecutar este Script me presente el siguiente Error

    C:\Script>cscript //nologo listar-caducidad-password-ad.vbs /F:c:\script\auditor
    ia\caducidad-password.tsv mooreve.net
    C:\Script\listar-caducidad-password-ad.vbs(89, 1) (null): Error no especificado

  4. urpiano said

    Jose Ramon Pernia Reyes,

    Prueba ahora, lo he corregido. En el dominio en el que lo creé no daba ese error, pero lo he probado en otro y sí lo da; ya lo he arreglado (al menos ahora a mí me funciona).

  5. Elis said

    Hola he probado el codigo pero me da error indicando que la tabla no existe, mi sistema de ldap es OpenLdap.. que cree a que se debe el error? agradeceria tu ayuda

  6. urpiano said

    Elis,

    Siento no haberte respondido antes, ultimamente ando muy liado…

    No te va a funcionar con OpenLdap, pues este script utiliza ADSI, que es la forma de trabajar desde scritp con el LDAP de Active Directory, no de otros LDAPs

  7. drotha2 said

    Hola,

    Veo que entiendes bastante del tema… yo pretendo hacer algo similar pero en maquinas locales, estoy añadiendo un usuario como administrador y quiero dejar marcada las casillas de usuario no puede cambiar la contraseña y la contraseña nunca caduca. puedes ayudarme???

    Saludos y gracias!

  8. Gonzalo said

    Yo también tuve el error C:\Script\listar-caducidad-password-ad.vbs(89, 1) (null): Error no especificado
    y mi humilde solución al problema es la siguiente:

    Agregar la linea siguiente en la declaración de las variables:
    Dim str_DominioDNS ‘As String

    Agregar la linea siguiente en la funcion f_RevisarArgumentos:
    str_DominioDNS = str_Dominio
    luego de la linea:
    str_Dominio = WScript.Arguments.Unnamed(0)

    Cambiar la linea 89 donde dice (Set obj_Dominio = GetObject(“WinNT://” & str_DominioNT)) por esta linea:
    Set obj_Dominio = GetObject(“WinNT://” & str_DominioDNS)

    saludos.

    • urpiano said

      Gonzalo,

      ¡Y sin embargo funciona! Veamos. En f_RevisarArgumentos, lo que se hace con str_DominioNT es tener el nombre NetBios del dominio, pues el script espera recibir el nombre DNS; por ejemplo:

      Nombre DNS: midominio.local
      Nombre NetBios: midominio

      Aunque generalmente el nombre NetBios de un dominio es igual a la parte más a la izquierda de su nombre DNS, esto no tiene porque ser así, pues al crear el dominio tu puedes especificar que tenga el nombre NetBios que quieras. Por ello el script usa el objeto NameTranslate, en la función f_NTaDN, para hallar el nombre NetBios del dominio a partir de su distinguido, que es montado anteriormente con la función Replace (el nombre distinguido del dominio midominio.local es dc=midominio,dc=local). ¿No será que el problema que teneis es que no pasais el nombre DNS si no el NetBios directamente, con lo que el objeto NameTranslate no es capaz de traducir nada?

  9. Alexis said

    Hola:

    Tenemos la GPO para que las contraseñas caduquen cada 60 dias, necesito un reporte de las proximas fechas de expiracion de contraseñas de algunos usuarios. Como soy medio nuevo en esto de las consultas al LDAP, no sé en que parte de tu script voy remplazando por los datos de mi dominio, que ficheros son los que debo crear, la ruta y demá. Espero tu ayuda.

    Un salu2

  10. Ciro said

    Hola queria saber que modificaciones habria que hacerle para que funcione en maquinas sin dominio?

    Gracias

    • urpiano said

      Ciro,

      El script cambia completamente. Además, que yo sepa, no se puede obtener con VbScript la fecha de caducidad de la contraseña, no es algo que tenga el objeto usuario local, cosa que sí tiene el usuario de dominio (no directamente, si no en base a su atributo pwLastSet y al atributo de dominio MaxPasswordAge). Esto no es posible con el usuario Local. Lo más que puedes es mirar las propiedades del usuario local para saber si caduca o no su cuenta. Por ejemplo, desde línea de comandos:

      wmic useraccount list full

  11. urpiano said

    Myriam,

    Puedes hacerlo perfectamente; basta con que cambies en el código la asignación que hace a la variable str_Dominio para que se le quede de valor el nombre distinguido de la OU que quieres listar.

  12. Daniel said

    Tiene algun limite de usuarios para listar??? a mi me aparece un error
    (218, 5) Microsoft VBScript runtime error: Invalid procedure
    call or argument

  13. Daniel FH said

    Me genera el siguiente error al correrlo,

    cscript //nologo listar-caducidad-password-ad.vbs /f:c:\listados\caducidad-cuentas.xls xxxx.local
    listar-caducidad-password-ad.vbs(248, 5) (null): 0x80005000

    Alguna idea?

    Saludos.

  14. Sondra said

    Can you tell us more about this? I’d love to find out more details.

  15. AFB said

    Hola,

    Me gustaría saber que pasos he de seguir para hacer lo mismo, pero introduciendo que envíe por correo una alerta a los usuarios que les falten 15 días para la caducidad de la contraseña.

    Muchas gracias.

  16. alfredoz24 said

    Hola a todos, me podrian apoyar please siempre quise hacer esto pero me muestra ese error:

    C:\>cscript //nologo listar-caducidad-password-ad.vbs /F:c:\script\auditoria\cad
    ucidad-password.tsv ausa.com.pe
    C:\listar-caducidad-password-ad.vbs(1, 1) Microsoft VBScript compilation error:
    Invalid character

    • Luison said

      Hola buenas.
      El error viene determinado por la codificación que estás usando.
      A mi me ocurrió que tenía el notepad++ en UTF-8 y guardé el fichero, cuando en windows utilizamos ansi, por lo que me daba ese error.
      Codificaló en ansi verás como se soluciona.
      Un salu2.

  17. David said

    Buenas,

    Muchas gracias por el script, me ha sido de gran utilidad.

    También tenía el problema que comentaba Gonzalo, pero al final lo solucioné añadiendo mi dominio en la siguiente línea:

    Set obj_Dominio = GetObject(“WinNT://mi_dominio”)

    Por otro lado, te quería una petición si no es mucho pedir… que es la de añadir una columna con las cuentas de correo de los usuarios, para poder avisar a los usuarios que tienen la cuenta caducada.

    Un saludo y muchas gracias.

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

 
A %d blogueros les gusta esto: