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 Cambiar La Configuración DNS De Varios Equipos

Posted by urpiano en Jueves 19 \19\UTC julio \19\UTC 2007

Este script permite eliminar los servidores DNS y establecer otros nuevos en varios equipos de forma remota. Utiliza WMI para realizar esta tarea.

Sintaxis

cscript [//nologo] cambiar-dns.vbs /L:listaDNS [/E:lista] [/F:fichero] [/O:fichero] [/U:usuario] [/C:contraseña] [/?]

Siendo

Etiqueta Dato ¿Requerido? Descripción
L listaDNS
Lista de servidores DNS, separados por coma, que se han de configurar. El orden en el que aparecen de izquierda a derecha es el orden que tendrán como servidores DNS.
E lista No
Nombres de los equipos, separados por comas, a los que se cambiarán los DNSs. Si no se recibe este argumento ni el argumento /F (fichero de texto con los nombres de equipos, uno por línea), se producirá un error y se terminará la ejecución del script. En el caso de que se pasen ambos argumentos, prevalecerá el argumento /F.
F fichero No
Ruta y nombre de un fichero de texto con los nombres de los equipos a los que se cambiará los DNSs. Si no se recibe este argumento ni el argumento /E (lista de los equipos separados por comas), se producirá un error y se terminará la ejecución del script. En el caso de que se pasen ambos argumentos, prevalecerá el argumento /F.
O fichero No
Ruta y nombre de un fichero al que se volcarán los resultados obtenidos. Se trata de un fichero de valores separados por tabuladores, ideal para ser abierto con Excel.
U usuario No
Nombre del usuario con el que se conectará al servicio WMI. Si el equipo local está incluído en la lista de los equipos, no se conectará con este usuario, si no con el usuario que lanza el script, pues no se puede conectar a WMI con credenciales alternativas en el equipo local.
C contraseña No
Contraseña del usuario de conexión. Este argumento será ignorado si no se pasa el argumento /U. En caso de ser pasado el argumento /U y no ser pasado este argumento, el script presentará una ventana de Internet Explorer en el que se pedirá al usuario que escriba la contraseña en una caja de texto de tipo password.
?   No
Muestra la ayuda en línea.

Ejemplos:

– Establece 192.168.0.200,192.168.0.201,192.168.0.202 como servidores DNS en los equipos gandalf,pippin,frodo:

cscript //nologo cambiar-dns.vbs /L:192.168.0.200,192.168.0.201,192.168.0.202 /E:gandalf,pippin,frodo

– Establece 192.168.0.200,192.168.0.201,192.168.0.202 como servidores DNS en los equipos contenidos en el fichero c:gondorequipos.txt:

cscript //nologo cambiar-dns.vbs /L:192.168.0.200,192.168.0.201,192.168.0.202 /F:c:gondorequipos.txt

– Establece 192.168.0.200,192.168.0.201,192.168.0.202 como servidores DNS en los equipos contenidos en el fichero c:gondorequipos.txt, conectando a WMI como el usuario gondoradministrator:

cscript //nologo cambiar-dns.vbs /L:192.168.0.200,192.168.0.201,192.168.0.202 /F:c:gondorequipos.txt /U:gondoradministrator

– Establece 192.168.0.200,192.168.0.201,192.168.0.202 como servidores DNS en los equipos contenidos en el fichero c:gondorequipos.txt, conectando a WMI como el usuario gondoradministrator, suministrando como contraseña de conexión Nunca la sabrás:

cscript //nologo cambiar-dns.vbs /L:192.168.0.200,192.168.0.201,192.168.0.202 /F:c:gondorequipos.txt /U:gondoradministrator
/C:"Nunca la sabrás"

– Establece 192.168.0.200,192.168.0.201,192.168.0.202 como servidores DNS en los equipos contenidos en el fichero c:gondorequipos.txt, conectando a WMI como el usuario gondoradministrator, suministrando como contraseña de conexión Nunca la sabrás. En lugar de mostrarse por pantalla, los resultados se almacenarán en el archivo e:gondorcambio-dns.txt:

cscript //nologo cambiar-dns.vbs /L:192.168.0.200,192.168.0.201,192.168.0.202 /F:c:gondorequipos.txt /O:e:gondorcambio-dns.txt /U:gondoradministrator /C:"Nunca la sabrás"

Este es el código del script

'*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*
'*°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°*
'* cambiar-dns.vbs                                                     *
'*                                                                     *
'* Este script permite eliminar los servidores DNS y establecer otros  *
'* nuevos en varios equipos de forma remota. Utiliza WMI para realizar *
'* esta tarea.                                                         *
'*                                                                     *
'* Sintaxis                                                            *
'*                                                                     *
'* cscript [//nologo] cambiar-dns.vbs /L:listaDNS [/E:lista]           *
'* [/F:fichero] [/O:fichero] [/U:usuario] [/C:contraseña] [/?]         *
'*                                                                     *
'* Siendo                                                              *
'*                                                                     *
'* - /L: listaDNS (Requerido):                                         *
'*         Lista de servidores DNS, separados por coma, que se han de  *
'*         configurar. El orden en el que aparecen de izquierda a      *
'*         derecha es el orden que tendrán como servidores DNS.        *
'*                                                                     *
'* - /E: lista (Opcional):                                             *
'*         Nombres de los equipos, separados por comas, a los que se   *
'*         cambiarán los DNSs. Si  no se recibe este argumento ni el   *
'*         argumento /F (fichero de texto con los nombres de equipos,  *
'*         uno por línea), se producirá un error y se terminará la     *
'*         ejecución del script. En el caso de que se pasen ambos      *
'*         argumentos, prevalecerá el argumento /F.                    *
'*                                                                     *
'* - /F: fichero (Opcional):                                           *
'*         Ruta y nombre de un fichero de texto con los nombres de los *
'*         equipos a los que se cambiará los DNSs. Si  no se recibe    *
'*         este argumento ni el argumento /E (lista de los equipos     *
'*         separados por comas), se producirá un error y se terminará  *
'*         la ejecución del script. En el caso de que se pasen ambos   *
'*         argumentos, prevalecerá el argumento /F.                    *
'*                                                                     *
'* - /O: fichero (Opcional):                                           *
'*         Ruta y nombre de un fichero al que se volcarán los          *
'*         resultados obtenidos. Se trata de un fichero de valores     *
'*         separados por tabuladores, ideal para ser abierto con Excel.*
'*                                                                     *
'* - /U: usuario (Opcional):                                           *
'*         Nombre del usuario con el que se conectará al servicio WMI. *
'*         Si el equipo local está incluído en la lista de los         *
'*         equipos, no se conectará con este usuario, si no con el     *
'*         usuario que lanza el script, pues no se puede conectar a    *
'*         WMI con credenciales alternativas en el equipo local.       *
'*                                                                     *
'* - /C: contraseña (Opcional):                                        *
'*         Contraseña del usuario de conexión. Este argumento será     *
'*         ignorado si no se pasa el argumento /U. En caso de ser      *
'*         pasado el argumento /U y no ser pasado este argumento, el   *
'*         script presentará una ventana de Internet Explorer en el    *
'*         que se pedirá al usuario que escriba la contraseña en una   *
'*         caja de texto de tipo password.                             *
'*                                                                     *
'* Ejemplos:                                                           *
'*                                                                     *
'* - Establece 192.168.0.200,192.168.0.201,192.168.0.202 como          *
'* servidores DNS en los equipos gandalf,pippin,frodo:                 *
'*                                                                     *
'* cscript //nologo cambiar-dns.vbs                                    *
'* /L:192.168.0.200,192.168.0.201,192.168.0.202 /E:gandalf,pippin,frodo*
'*                                                                     *
'* - Establece 192.168.0.200,192.168.0.201,192.168.0.202 como          *
'* servidores DNS en los equipos contenidos en el fichero              *
'* c:gondorequipos.txt:                                              *
'*                                                                     *
'* cscript //nologo cambiar-dns.vbs                                    *
'* /L:192.168.0.200,192.168.0.201,192.168.0.202                        *
'* /F:c:gondorequipos.txt                                            *
'*                                                                     *
'* - Establece 192.168.0.200,192.168.0.201,192.168.0.202 como          *
'* servidores DNS en los equipos contenidos en el fichero              *
'* c:gondorequipos.txt, conectando a WMI como el usuario             *
'* gondoradministrator:                                               *
'*                                                                     *
'* cscript //nologo cambiar-dns.vbs                                    *
'* /L:192.168.0.200,192.168.0.201,192.168.0.202                        *
'* /F:c:gondorequipos.txt /U:gondoradministrator                    *
'*                                                                     *
'* - Establece 192.168.0.200,192.168.0.201,192.168.0.202 como          *
'* servidores DNS en los equipos contenidos en el fichero              *
'* c:gondorequipos.txt, conectando a WMI como el usuario             *
'* gondoradministrator, suministrando como contraseña de conexión     *
'* Nunca la sabrás:                                                    *
'*                                                                     *
'* cscript //nologo cambiar-dns.vbs                                    *
'* /L:192.168.0.200,192.168.0.201,192.168.0.202                        *
'* /F:c:gondorequipos.txt /U:gondoradministrator /C:"Nunca la       *
'* sabrás"                                                             *
'*                                                                     *
'* - Establece 192.168.0.200,192.168.0.201,192.168.0.202 como          *
'* servidores DNS en los equipos contenidos en el fichero              *
'* c:gondorequipos.txt, conectando a WMI como el usuario             *
'* gondoradministrator, suministrando como contraseña de conexión     *
'* Nunca la sabrás. En lugar de mostrarse por pantalla, los resultados *
'* se almacenarán en el archivo e:gondorcambio-dns.txt:              *
'*                                                                     *
'* cscript //nologo cambiar-dns.vbs                                    *
'* /L:192.168.0.200,192.168.0.201,192.168.0.202                        *
'* /F:c:gondorequipos.txt /O:e:gondorcambio-dns.txt                *
'* /U:gondoradministrator /C:"Nunca la sabrás"                        *
'*                                                                     *
'*                                                                     *
'*                                                                     *
'* © Fernando Reyes                                                    *
'* Julio De 2007                                                       *
'*°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°*
'*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*

'Exigimos la declaración de variables
Option Explicit


Dim str_Error 'As String
Dim int_Error 'As String
Dim arr_st_DNS 'As String
Dim arr_st_Equipos 'As String
Dim str_TXT 'As String
Dim str_Usuario 'As String
Dim str_Clave 'As String
Dim int_Equipo 'As Integer
Dim str_Mensaje 'As String

'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

str_Mensaje = "Equipo" & vbTab & _
              "Nº Configuración" & vbTab & _
              "Servidores Antes" & vbTab & _
              "¿Se Cambió?" & vbTab & _
              "Servidores Después"
         
If Len(str_TXT) > 0 Then str_Mensaje = str_Mensaje & vbCrLf

For int_Equipo = LBound(arr_st_Equipos) To UBound(arr_st_Equipos)

    If Not f_ProcesarEquipo(arr_st_Equipos(int_Equipo)) Then
    
        str_Mensaje = str_Mensaje & arr_st_Equipos(int_Equipo) & _
                      vbTab & "Falló en el procesamiento" & _
                      vbCrLf & vbCrLf
                      
    Else
    
'        str_Mensaje = str_Mensaje & vbCrLf
        
    End If
    
    'Como no se ha recibido el parámetro O (fichero de
    'salida), mostramos el resultado por pantalla
    If Len(str_TXT) = 0 Then 
    
        WScript.Echo str_Mensaje
        str_Mensaje = ""
        
    Else
    
        str_Mensaje = str_Mensaje & vbCrLf
        
    End If

Next 'int_Equipo

If Len(str_TXT) > 0 Then

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

    Set obj_FS = CreateObject("Scripting.FileSystemObject")
    Set obj_TS = obj_FS.CreateTextFile(str_TXT)

    obj_TS.Write str_Mensaje
    
    obj_TS.Close
    Set obj_TS = Nothing
    Set obj_FS = Nothing
    
End If

WScript.Quit 0

Function f_ProcesarEquipo(str_Equipo) 'As Boolean
'***********************************************************************
'* Procedimiento: f_ProcesarEquipo                                     *
'* Tipo         : Función                                              *
'* Devolución   : Booleana                                             *
'* Fecha y Hora : 19/07/2007 12:25:05                                  *
'* Autor        : Fernando Reyes                                       *
'*¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯*
'* Propósito    : Esta función permite cambiar los DNSs del equipo     *
'*                recibido como parámetro. En caso de tener éxito,     *
'*                devuelve True, en caso contrario False. Para hacer   *
'*                esto, utiliza el método SetDNSServerSearchOrder del  *
'*                objeto Win32_NetworkAdapterConfiguration de WMI.     *
'*                Está basada en el script Dns-replaceserverlist.vbs   *
'*                del artículo:                                        *
'*http://www.microsoft.com/technet/scriptcenter/topics/networking/05_a *
'*tnc_dns.mspx                                                         *
'***********************************************************************


    Dim bol_Devolucion  'As Boolean
    Dim obj_ServicioWMI 'As SWbemScripting.SWbemServices
    Dim obj_ConfiguracionNIC 'As WMIClasses. _
                       'Win32_NetworkAdapterConfiguration
    Dim col_ConfiguracionNICs 'As WMIClasses. _
            'Win32_NetworkAdapterConfiguration collection
    Dim str_ServidoresDNS 'As String
    Dim int_Devolucion 'As Integer
    Dim bol_PrimeroMostrado 'As Boolean
    Dim arr_SiguientesAntes() 'As String
    Dim arr_SiguientesDespues() 'As String
    Dim int_SiguienteAntes 'As Integer
    Dim int_SiguienteDespues 'As Integer
    Dim int_Siguiente 'As Integer
    Dim str_Siguientes 'As Integer
    Dim int_Ciclos 'As Integer
    
    'Conectamos con el servicio WMI del equipo
    If Not f_ServicioWMI(obj_ServicioWMI, _
                         str_Usuario, _
                         str_Clave, _
                         str_Equipo,_
                         "rootCIMV2") Then
                         
        'No se ha podido conectar, lo indicamos y salimos de la´
        'función devolviendo False
        str_Mensaje = str_Mensaje & _
                      str_Equipo & vbTab & _
                      "No se pudo conectar a WMI" & vbCrLf
                      
        f_ProcesarEquipo = False
        
    End If
    
    'Establecemos control de errores
    On Error Resume Next
     
    'Hacemos la consulta de las configuraciones, con IP
    'habilitada, de los adaptadores de red
    Set col_ConfiguracionNICs = obj_ServicioWMI.ExecQuery _
     ("SELECT * FROM Win32_NetworkAdapterConfiguration " & _
                                 "WHERE IPEnabled = True")
     
    'Recorremos los adaptadores encontrados
    For Each obj_ConfiguracionNIC In col_ConfiguracionNICs
    
        'Ponemos el nombre del equipo en el mensaje
        str_Mensaje = str_Mensaje & str_Equipo
        
        'Ponemos el número de índice de la configuración
        'del adaptador
        str_Mensaje = str_Mensaje & vbTab & _
                                obj_ConfiguracionNIC.Index & vbTab
                                
        'Vamos ahora a poner la configuración DNS que tiene el
        'adaptador
        If Not IsNull(obj_ConfiguracionNIC.DNSServerSearchOrder) Then
        
            'Recorremos los diferentes servidores confiurados
            For Each str_ServidoresDNS In _
                            obj_ConfiguracionNIC.DNSServerSearchOrder
            
                'Si no es el primero..
                If bol_PrimeroMostrado Then
            
                    'Tenemos que volcar su información en otra línea;
                    'creamos un elemento en el array con el que
                    'montaremos la nueva línea
                    ReDim Preserve arr_SiguientesAntes( _
                                                 int_SiguienteAntes)
                    
                    'Volcamos el servidor en el elemento creado
                    arr_SiguientesAntes(int_SiguienteAntes) = _
                                                   str_ServidoresDNS
                    
                    'Incrementamos el contador de líneas
                    int_SiguienteAntes = int_SiguienteAntes + 1
                                  
                Else
                
                    'Marcamos que ya hemos mostrado el primer
                    'servidor
                    bol_PrimeroMostrado = True
                    
                    'Ponemos el servidor en el mensaje
                    str_Mensaje = str_Mensaje & str_ServidoresDNS
                
                End If
                
            Next
            
            'Reiniciamos el marcador de primero ya encontrado para
            'la siguiente vuelta
            bol_PrimeroMostrado = False
            
        End If
        
        'Procedemos a cambiar la configuración DNS
        int_Devolucion = _
            obj_ConfiguracionNIC.SetDNSServerSearchOrder( _
                                                     arr_st_DNS)
            
        'Si la devolución es correcta...
        If int_Devolucion = 0 Then
        
            'Marcamos en el mensaje que ha sido cambiado
            str_Mensaje = str_Mensaje & vbTab & "Sí"
            
        'Si no ha sido correcta...
        Else
        
            'Marcamos que no se ha podido cambiar
            str_Mensaje = str_Mensaje & vbTab & "No"
            
        End If
        
    Next
     
    'Hacemos un bucle idéntico al anterior, para obtener los nuevos
    'servidores configurados
    Set col_ConfiguracionNICs = obj_ServicioWMI.ExecQuery _
     ("SELECT * FROM Win32_NetworkAdapterConfiguration " & _
                                "WHERE IPEnabled = True")
     
    For Each obj_ConfiguracionNIC In col_ConfiguracionNICs
    
      If Not IsNull(obj_ConfiguracionNIC.DNSServerSearchOrder) Then
      
        For Each str_ServidoresDNS In _
                          obj_ConfiguracionNIC.DNSServerSearchOrder
        
            'Al igual que hicimos antes, debemos volcar en una
            'nueva línea cada uno de los que halla por encima
            'del primero. Esta vez lo hacemos en el array de
            'siguientes de después
            If bol_PrimeroMostrado Then
            
                    ReDim Preserve arr_SiguientesDespues( _
                                                int_SiguienteDespues)
                    arr_SiguientesDespues(int_SiguienteDespues) = _
                                                 str_ServidoresDNS
                    int_SiguienteDespues = int_SiguienteDespues + 1
            
            Else
            
                bol_PrimeroMostrado = True
                str_Mensaje = str_Mensaje & vbTab & _
                                        str_ServidoresDNS
                
            End If
          
        Next
        
      End If
      
    Next
    
    'Si tenemos anteriores o siguientes,procedermos a volcar la
    'información en el mensaje. Eso lo haremos en un bucle FOR.
    'En este If obtendremos cuál es el límite superior hasta el
    'que debe llegar el bucle (el inferior siempre será 0)
    If int_SiguienteAntes >= int_SiguienteDespues _
    And int_SiguienteAntes > 0 Then
    
        'El límite del array de antes es superior o igual al
        'de después y superior a cero; de esta manera
        'evitamos que se pueda intentar recorrer arrays vacíos,
        'lo que provoca un error (si hay un primer elemento el
        'valor del contador es 1)        
        int_Ciclos = int_SiguienteAntes
    
    ElseIf int_SiguienteDespues > 0 Then
    
        'El límite de después es el superior y es mayor
        'que cero
        int_Ciclos = int_SiguienteDespues
    
    End If
    
    'Si hay al menos uin elemento en algún array
    If int_Ciclos >= 0 Then
    
        For int_Siguiente = 0 To int_Ciclos - 1
        
            'Si existe el elemento en el array de antes...
            If int_Siguiente <= int_SiguienteAntes -1 Then
            
                'lo volcamos en la nueva línea
                str_Siguientes = str_Siguientes & _
                                    String(2,vbTab) & _
                                    arr_SiguientesAntes(_
                                            int_Siguiente)
                
            'si no lo lo hay...
            Else
            
                'lo dejamos vacío
                str_Siguientes = str_Siguientes & _
                                    String(3,vbTab)
                
            End If

            'Si existe el elemento en el array de después...
            If int_Siguiente <= int_SiguienteDespues -1 Then
            
                'Lo volcamos en la nueva línea
                str_Siguientes = str_Siguientes & _
                                    String(2,vbTab) & _
                                    arr_SiguientesDespues(_
                                            int_Siguiente) & _
                                    vbCrLf
                
            'si no lo lo hay...
            Else
            
                'lo dejamos vacío
                str_Siguientes = str_Siguientes & _
                                    String(2,vbTab) & vbCrLf
                
            End If
        
        Next 'int_Siguiente
        
        'Quitamos el salto de línea final
        If Len(str_Siguientes) > 0 Then _
            str_Siguientes = Left(str_Siguientes, _
                                  Len(str_Siguientes)-2)
        'Añadimos los DNS siguientes al mensaje
        str_Mensaje = str_Mensaje & vbCrLf & str_Siguientes
    
    End If

    'Si hemos llegado hasta aquí, todo ha sido correcto, y
    'así lo reflejamos en la devolución
    f_ProcesarEquipo = True
    
    Set obj_ServicioWMI = Nothing

End Function 'f_ProcesarEquipo



Function f_RevisarArgumentos( _
                             str_Error, _
                             int_Error _
                             ) 'As Boolean
'***********************************************************************
'* Procedimiento: f_RevisarArgumentos                                  *
'* Tipo         : Función                                              *
'* Devolución   : Booleana                                             *
'* Fecha y Hora : 18/07/2007 13:04:53                                  *
'* 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 dos tipos de error;      *
'*                error 1 para los parámetros sin nombre requeridos y  *
'*                error 2 para los parámetros con nombre requeridos.   *
'*                En el caso de producirse ambos tipos de errores, el  *
'*                número de error será la suma de ambos: 3             *
'***********************************************************************

    Dim bol_Devolucion 'As Boolean
    Dim bol_Error1 'As Boolean
    Dim bol_Error2 'As Boolean
    Dim obj_FS 'As Scripting.FileSystemObject
    Const ForReading = 1
    Const TristateFalse = -1
    Dim obj_TS 'As Scripting.TextStream

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

    'Revisamos que esté el argumento requerido
    '/L (listaDNS)
    If WScript.Arguments.Named.Exists("L") Then

        arr_st_DNS =  _
               Split(WScript.Arguments.Named("L"),",")

    Else

        str_Error = str_Error & vbcrlf & _
                    "Error 2, falta argumento " & _
                    "requerido con nombre: " & _
                    "/L (listaDNS)"
        bol_Error2 = True

    End If

    'Revisamos si ha sido pasado el argumento
    '/F (fichero)
    If WScript.Arguments.Named.Exists("F") Then

        Set obj_FS = CreateObject("Scripting.FileSystemObject")
        Set obj_TS = obj_FS.OpenTextFile(WScript.Arguments.Named("F"))

        arr_st_Equipos = _
            Split(obj_TS.ReadAll,vbCrLf)

        obj_TS.Close
        Set obj_TS = Nothing
        Set obj_FS = Nothing
        
    'Revisamos si ha sido pasado el argumento
    '/E (lista)
    ElseIf WScript.Arguments.Named.Exists("E") Then

        arr_st_Equipos =  _
               Split(WScript.Arguments.Named("E"),",")

    
    Else
    
        str_Error = str_error & vbcrlf & _
                    "Error 4, no se ha pasado ninguno de los " & _
                    "argumentos integrantes de un combo: /E (" & _
                    "lista de equipos) y /F (Fichero con la l" & _
                    "ista de equipos)."
        int_Error = 4
        f_RevisarArgumentos = True
        Exit Function
    
    End If

    'Revisamos si ha sido pasado el argumento
    '/O (fichero)
    If WScript.Arguments.Named.Exists("O") Then

        str_TXT = WScript.Arguments.Named("O")

    End If

    'Revisamos si ha sido pasado el argumento
    '/U (usuario)
    If WScript.Arguments.Named.Exists("U") Then

        str_Usuario =  _
               WScript.Arguments.Named("U")

        'Revisamos si ha sido pasado el argumento
        '/C (contraseña)
        If WScript.Arguments.Named.Exists("C") Then
    
            str_Clave =  _
                   WScript.Arguments.Named("C")
                   
        Else
        
            str_Clave = f_EntrarClave("\fernandor-fusuario-conexion")
    
        End If

    End If


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

    '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 : 19/07/2007 18:55:40                                  *
'* Autor        : Fernando Reyes                                       *
'*¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯*
'* Propósito    : Este procedimiento muestra la ayuda en línea.        *
'*                Recibe un parámetro de tipo cadena que si no viene   *
'*                será mostrado antes de la línea; pensado para que    *
'*                se muestre un error que se haya detectado.           *
'***********************************************************************

    If Len(str_Error) > 0 Then

        WScript.Echo str_Error & vbCrLf & vbCrLf

    End If

    WScript.Echo "Este script permite eliminar los servidores DNS y" & _
                 " establecer otros nuevos en"
    WScript.Echo "varios equipos de forma remota. Utiliza WMI para " & _
                 "realizar esta tarea."
    WScript.Echo ""
    WScript.Echo "Sintaxis"
    WScript.Echo ""
    WScript.Echo "cscript [//nologo] cambiar-dns.vbs /L:listaDNS [/" & _
                 "E:lista] [/F:fichero]"
    WScript.Echo "[/O:fichero] [/U:usuario] [/C:contraseña] [/?]"
    WScript.Echo ""
    WScript.Echo "Siendo"
    WScript.Echo ""
    WScript.Echo "- /L: listaDNS (Requerido):"
    WScript.Echo "Lista de servidores DNS, separados por coma, que " & _
                 "se han de"
    WScript.Echo "configurar. El orden en el que aparecen de izquie" & _
                 "rda a derecha"
    WScript.Echo "es el orden que tendrán como servidores DNS."
    WScript.Echo ""
    WScript.Echo "- /E: lista (Opcional):"
    WScript.Echo "Nombres de los equipos, separados por comas, a lo" & _
                 "s que se"
    WScript.Echo "cambiarán los DNSs. Si  no se recibe este argumen" & _
                 "to ni el"
    WScript.Echo "argumento /F (fichero de texto con los nombres de" & _
                 " equipos, uno"
    WScript.Echo "por línea), se producirá un error y se terminará " & _
                 "la ejecución"
    WScript.Echo "del script. En el caso de que se pasen ambos argu" & _
                 "mentos,"
    WScript.Echo "prevalecerá el argumento /F."
    WScript.Echo ""
    WScript.Echo "- /F: fichero (Opcional):"
    WScript.Echo "Ruta y nombre de un fichero de texto con los nomb" & _
                 "res de los"
    WScript.Echo "equipos a los que se cambiará los DNSs. Si  no se" & _
                 " recibe este"
    WScript.Echo "argumento ni el argumento /E (lista de los equipo" & _
                 "s separados"
    WScript.Echo "por comas), se producirá un error y se terminará " & _
                 "la ejecución"
    WScript.Echo "del script. En el caso de que se pasen ambos argu" & _
                 "mentos,"
    WScript.Echo "prevalecerá el argumento /F."
    WScript.Echo ""
    WScript.Echo "- /O: fichero (Opcional):"
    WScript.Echo "Ruta y nombre de un fichero al que se volcarán lo" & _
                 "s resultados"
    WScript.Echo "obtenidos. Se trata de un fichero de valores sepa" & _
                 "rados por"
    WScript.Echo "tabuladores, ideal para ser abierto con Excel."
    WScript.Echo ""
    WScript.Echo "- /U: usuario (Opcional):"
    WScript.Echo "Nombre del usuario con el que se conectará al ser" & _
                 "vicio WMI. Si"
    WScript.Echo "el equipo local está incluído en la lista de los " & _
                 "equipos, no se"
    WScript.Echo "conectará con este usuario, si no con el usuario " & _
                 "que lanza el"
    WScript.Echo "script, pues no se puede conectar a WMI con crede" & _
                 "nciales"
    WScript.Echo "alternativas en el equipo local."
    WScript.Echo ""
    WScript.Echo "- /C: contraseña (Opcional):"
    WScript.Echo "Contraseña del usuario de conexión. Este argument" & _
                 "o será"
    WScript.Echo "ignorado si no se pasa el argumento /U. En caso d" & _
                 "e ser pasado"
    WScript.Echo "el argumento /U y no ser pasado este argumento, e" & _
                 "l script"
    WScript.Echo "presentará una ventana de Internet Explorer en el" & _
                 " que se pedirá"
    WScript.Echo "al usuario que escriba la contraseña en una caja " & _
                 "de texto de"
    WScript.Echo "tipo password."
    WScript.Echo ""
    WScript.Echo "Ejemplos:"
    WScript.Echo ""
    WScript.Echo "- Establece 192.168.0.200,192.168.0.201,192.168.0" & _
                 ".202 como servidores DNS en"
    WScript.Echo "los equipos gandalf,pippin,frodo:"
    WScript.Echo ""
    WScript.Echo "cscript //nologo cambiar-dns.vbs /L:192.168.0.200" & _
                 ",192.168.0.201,192.168.0.202"
    WScript.Echo "/E:gandalf,pippin,frodo"
    WScript.Echo ""
    WScript.Echo "- Establece 192.168.0.200,192.168.0.201,192.168.0" & _
                 ".202 como servidores DNS en"
    WScript.Echo "los equipos contenidos en el fichero c:gondoreq" & _
                 "uipos.txt:"
    WScript.Echo ""
    WScript.Echo "cscript //nologo cambiar-dns.vbs /L:192.168.0.200" & _
                 ",192.168.0.201,192.168.0.202"
    WScript.Echo "/F:c:gondorequipos.txt"
    WScript.Echo ""
    WScript.Echo "- Establece 192.168.0.200,192.168.0.201,192.168.0" & _
                 ".202 como servidores DNS en"
    WScript.Echo "los equipos contenidos en el fichero c:gondoreq" & _
                 "uipos.txt, conectando a WMI"
    WScript.Echo "como el usuario gondoradministrator:"
    WScript.Echo ""
    WScript.Echo "cscript //nologo cambiar-dns.vbs /L:192.168.0.200" & _
                 ",192.168.0.201,192.168.0.202"
    WScript.Echo "/F:c:gondorequipos.txt /U:gondoradministrator"
    WScript.Echo ""
    WScript.Echo "- Establece 192.168.0.200,192.168.0.201,192.168.0" & _
                 ".202 como servidores DNS en"
    WScript.Echo "los equipos contenidos en el fichero c:gondoreq" & _
                 "uipos.txt, conectando a WMI"
    WScript.Echo "como el usuario gondoradministrator, suministran" & _
                 "do como contraseña de conexión"
    WScript.Echo "Nunca la sabrás:"
    WScript.Echo ""
    WScript.Echo "cscript //nologo cambiar-dns.vbs /L:192.168.0.200" & _
                 ",192.168.0.201,192.168.0.202"
    WScript.Echo "/F:c:gondorequipos.txt /U:gondoradministrator " & _
                 "/C:""Nunca la sabrás"""
    WScript.Echo ""
    WScript.Echo "- Establece 192.168.0.200,192.168.0.201,192.168.0" & _
                 ".202 como servidores DNS en"
    WScript.Echo "los equipos contenidos en el fichero c:gondoreq" & _
                 "uipos.txt, conectando a WMI"
    WScript.Echo "como el usuario gondoradministrator, suministran" & _
                 "do como contraseña de conexión"
    WScript.Echo "Nunca la sabrás. En lugar de mostrarse por pantal" & _
                 "la, los resultados se"
    WScript.Echo "almacenarán en el archivo e:gondorcambio-dns.txt:"
    WScript.Echo ""
    WScript.Echo "cscript //nologo cambiar-dns.vbs /L:192.168.0.200" & _
                 ",192.168.0.201,192.168.0.202"
    WScript.Echo "/F:c:gondorequipos.txt /O:e:gondorcambio-dns." & _
                 "txt /U:gondoradministrator"
    WScript.Echo "/C:""Nunca la sabrás"""
    WScript.Echo ""
    WScript.Echo ""

End Sub 's_Ayuda

Function f_ServicioWMI(obj_ServicioWMI, str_Usuario, _
                       str_Clave, str_Equipo, _
                       str_Espacio)
'***********************************************************************
'* Procedimiento: f_ServicioWMI                                        *
'* Tipo         : Función                                              *
'* Devolución   : Booleana                                             *
'* Fecha y Hora : May 2007                                             *
'* Autor        : Fernando Reyes                                       *
'*¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯*
'* Propósito    : Esta función permite conectar con el servicio WMI    *
'*                de un equipo. La conexión puede ser realizada        *
'*                directamente por el usuario que ha lanzado el        *
'*                script o por otro usuario cuyas credenciales son     *
'*                recibidas como parámetros. La función recibe como    *
'*                parámetro un objeto que será utilizado como          *
'*                parámetro de salida, siendo creado por la función    *
'*                como objeto de servicio WMI del equipo recibido      *
'*                como parámetro. Si recibe usuario, contraseña y      *
'*                nombre de equipo a conectar, conectará con ése       *
'*                equipo con las credenciales pasadas, siempre y       *
'*                cuando no se trate del equipo local, en cuyo caso    *
'*                no se conectará con credenciales alternativas si no  *
'*                con el usuario que lanza el script. Si está vacío    *
'*                el parámetro str_Espacio, se conectará con el        *
'*                espacio de nombres rootCIMV2, en caso contrario     *
'*                con el espacio pasado.                               *
'***********************************************************************

    Dim obj_LocalizadorWMI
    Dim lng_Respuesta

    If Len(str_Espacio) = 0 Then str_Espacio = "rootCIMV2"

    'Si hemos recibido nombre de usuario, debemos conectar
    'al servicio WMI del equipo como el usuario
    'recibido. en el caso de que se trate del equipo local
    'ignoramos las credenciales alternativas
    If Len(str_Usuario) > 0 _
    And Not f_EquipoLocal(str_Equipo) Then

        'Para poder especificar unas credenciales alternativas,
        'debemos crear primero un localizador WMI
        Set obj_LocalizadorWMI = CreateObject( _
                                  "WbemScripting.SWbemLocator")

        'Establecemos control de errores
        On Error Resume Next

        'Conectamos con el servicio WMI del equipo con las
        'credenciales pasadas
        Set obj_ServicioWMI = obj_LocalizadorWMI.ConnectServer( _
                                       str_Equipo, str_Espacio, _
                                       str_Usuario, str_Clave)

        'Si se ha producido algún error...
        If Err.Number <> 0 Then

            'Lo primero es vaciar la variable con el localizador WMI
            Set obj_LocalizadorWMI = Nothing

            'Mostramos el error
            WScript.Echo vbCrLf & vbCrLf & _
                         Err.Number & ": " & Err.Description

            'Vaciamos el objeto Err
            Err.Clear

            'Devolvemos False
            f_ServicioWMI = False

            'Salimos de la función
            Exit Function

        End If

    Else

        'Podemos conectar directamente con el servicio WMI del
        'equipo sin necesidad de utilizar el localizador WMI
        'ya que no hay que hacerlo con otras credenciales
        'distintas a las del usuario que lanza el script
        Set obj_ServicioWMI = GetObject("winmgmts:\" & _
                                    str_Equipo & "" & _
                                    str_Espacio)

        'si se ha producido algún error...
        If Err.Number <> 0 Then

            'Mostramos el error
            WScript.Echo Err.Number & ": " & Err.Description & _
                         vbCrLf & vbCrLf

            'Vaciamos el objeto Err
            Err.Clear

            'Devolvemos False
            f_ServicioWMI = False

            'Salimos de la función
            Exit Function

        End If

    End If

    'No se han producido errores, devolvemos True
    f_ServicioWMI = True

    'Limpieza de culito :-)
    Set obj_LocalizadorWMI = Nothing

End Function 'f_ServicioWMI


Function f_EquipoLocal(str_Equipo)
'***********************************************************************
'* Procedimiento: f_EquipoLocal                                        *
'* Tipo         : Función                                              *
'* Devolución   : Booleana                                             *
'* Fecha y Hora : May 2007                                             *
'* Autor        : Fernando Reyes                                       *
'*¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯*
'* Propósito    : Esta función recibe un nombre de equipo y comprueba  *
'*                si se trata del equipo local o de uno remoto. Si es  *
'*                el equipo local devuelve True, si es remoto False.   *
'*                De paso, si como nombre de equipo local recibió "."  *
'*                cambiará en la variable recibida al nombre           *
'*                verdadero del equipo                                 *
'***********************************************************************

    Dim obj_SH, str_EquipoEntorno

    f_EquipoLocal = False

    'Creamos un objeto WshShell
    Set obj_SH = CreateObject("WScript.Shell")

    'Obtenemos el valor de la variable de entorno con
    'el nombre de equipo
    str_EquipoEntorno = UCase( _
       obj_SH.ExpandEnvironmentStrings("%COMPUTERNAME%"))

    'Si está vacío el nombre de equipo, o es ".",
    'se trata del equipo local; lo asignamos a la
    'variable
    If Len(str_Equipo) = 0 _
    Or str_Equipo = "." Then


        str_Equipo = str_EquipoEntorno
        f_EquipoLocal = True

    'Ahora revisamos no se haya pasado el FQDN del equipo
    'local o su nombre NetBios
    ElseIf _
        ( _
        Len(str_Equipo) > Len(str_EquipoEntorno) _
        And UCase(Left(str_Equipo, Len(str_EquipoEntorno))) = _
                      UCase(str_EquipoEntorno) _
        And Mid(str_Equipo, Len(str_EquipoEntorno) + 1, 1) = _
                      "." _
        ) _
    Or UCase(str_Equipo) = UCase(str_EquipoEntorno) Then

            str_Equipo = str_EquipoEntorno
            f_EquipoLocal = True

    End If

End Function 'f_EquipoLocal


Function f_EntrarClave(str_HTML)
'***********************************************************************
'* Procedimiento: f_EntrarClave                                        *
'* Tipo         : Función                                              *
'* Devolución   : Cadena                                               *
'* Fecha y Hora : May 2007                                             *
'* Autor        : Fernando Reyes                                       *
'*¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯*
'* Propósito    : El propósito de esta función es el proveer al        *
'*                usuario de una caja de texto en la que teclear una   *
'*                contraseña sin revelarla, pues la caja de texto es   *
'*                de tipo password. Para ello se crea una página web   *
'*                que es cargada en un Internet Explorer y se recoge   *
'*                de éste la contraseña tecleada y se convierte en la  *
'*                devolucion de la función. La ruta y nombre de la     *
'*                página es recibida como parámetro por la función,    *
'*                lo que permite reutilizar esta función en más        *
'*                scripts y personalizar la página para cada script,   *
'*                lo único que debe ser igual en todas las páginas     *
'*                que se quieran utilizar es que el botón debe         *
'*                llamarse Aceptar, el control oculto AceptarPulsado   *
'*                y la caja de texto Clave.                            *
'*                                                                     *
'*                Esta función está basada en:                         *
'*http://www.microsoft.com/technet/scriptcenter/guide/sas_ent_lppm.msp
'*x?mfr=true
'*                                                                     *
'*                En el ejemplo de TechNet se pone una ruta local      *
'*                (c:carpetafichero.asp) para la ubicación del       *
'*                fichero. Esto no es correcto cuando estamos de XP    *
'*                SP2 en adelante, pues la navegación segura           *
'*                interfiere con el script, ya que contiene un script  *
'*                VBScript. Para evitar esto, yo lo que hago es        *
'*                situar el fichero en una carpeta compartida y        *
'*                acceder a él con su ruta UNC; de esta manera es      *
'*                tratado como de la zona de intranet y no hay         *
'*                problemas. También se podría colocar en un servidor  *
'*                Web que fuese de la intranet o de los sitios de      *
'*                confianza y referirse a él por su ruta http; la      *
'*                mejor opción de todas sería situarlo en un servidor  *
'*                web seguro, y poner su ruta https, de esa manera     *
'*                eludimos a alguien que esté usando un sniffer        *
'*                                                                     *
'*                El código de la página puede ser tan simple como:    *
'*                <html>                                               *
'*                <script language="VBScript">                         *
'*                <!--                                                 *
'*                Sub Aceptar_OnClick()                                *
'*                                                                     *
'*                AceptarPulsado.Value = "Pulsado"                     *
'*                                                                     *
'*                End Sub                                              *
'*                -->                                                  *
'*                </script>                                            *
'*                <body>                                               *
'*                Entre la contraseña del usuario con el que se        *
'*                conectará al servicioWMI del equipo:                 *
'*                <input type="password" name ="Clave" size="20">      *
'*                <p><input name="Aceptar" type="button"               *
'*                value="Aceptar" ></p>                                *
'*                <p><input type="hidden" name="AceptarPulsado"        *
'*                size="20"></p>                                       *
'*                </body></html>                                       *
'***********************************************************************

    'Declaramos variables
    Dim obj_IE

    'Creamos un objeto Internet Explorer
    Set obj_IE = WScript.CreateObject _
              ("InternetExplorer.Application", "IE_")

    'Cargamos el navegador con la página recibida como parámetro
    obj_IE.Navigate str_HTML

    'Con este bucle esperamos a que la página esté completamente cargada
    Do

        WScript.Sleep 10

    Loop Until obj_IE.ReadyState = 4

    'Establecemos propiedades del navegador
    obj_IE.Toolbar = 0
    obj_IE.StatusBar = 0
    obj_IE.Width = 400
    obj_IE.Height = 250
    obj_IE.Left = 0
    obj_IE.Top = 0
    obj_IE.Visible = 1

    'En este bucle esperamos a que se haya pulsado el botón
    '"Aceptar"
    Do While (obj_IE.Document.All.AceptarPulsado.Value = "")

        WScript.Sleep 250

    Loop

    'Recogemos la contraseña entrada
    str_Clave = obj_IE.Document.All.Clave.Value

    'Cerramos el navegador
    obj_IE.Quit

    'Esperamos a que esté cerrado
    WScript.Sleep 250

    'Establecemos la contraseña como devolución de la función
    f_EntrarClave = str_Clave

    'Limpiadita de culito :-)
    Set obj_IE = Nothing

End Function 'f_EntrarClave

 

 

Anuncios

6 comentarios to “Script VBScript Para Cambiar La Configuración DNS De Varios Equipos”

  1. Erich Reyes said

    Hola esta excelente el script, una pregunta hay forma de elegir a que tarjeta de red se le cambia los DNS? ya que al correr el script cambia los dns en el cliente pero en las tarjeta de red alambrica y en la inalambrica, hay forma de hacerlo solo para una de ellas?

    Muchas gracias, y felicidades por el script esta muy bueno y me ha sido de gran utilidad.

  2. […] Recientes Erich Reyes en Script VBScript Para Cambiar L…urpiano en Cómo Recuperar Correos Borrad…Ricardo en Cómo Recuperar Correos Borrad…urpiano en […]

  3. urpiano said

    Erich Reyes:

    Mira si este nuevo script te es de más utilidad.

  4. Erich Reyes said

    Muchas gracias ya lo probe y esta excelente, saludos

  5. Christian said

    Hola !!! El sript esta fenomenal.. pero estoy afrontando un problema.. las estaciones de trabajo tienen un DNS definido el cual deseo camvbiar.. pero este por alguna razón no ejecuta por GPO, sólo si lo ejecyta el usuario….

    Gracias!!!!

  6. urpiano said

    Christian,

    El script está más pensado para lanzarlo desde otro equipo que para ser lanzado como script de inicio. No obstante, si lo quieres hacer por GPO, debes tener en cuenta qué tipo de script has configurado en la GPO (de inicio de equipo o de inicio de seesión) y por tanto dónde debe estar vinculada la GPO, para que afecte a la cuenta del equipo o del usuario. En este caso, lo recomendable sería que fuese ejecutado en un script de inicio de equipo, y por tanto que la GPO estuviese vinculada a la OU donde estén , ya sea de forma directa o por pertenecer a OU contenidas por la OU a la que se vincula, las cuentas de los equipos a los que debe afectar. Haciéndolo de esta manera, no es necesario que pases usuario y contraseña, pues el usuario que ejecuta unscript de inicio de equipo es el usuario SYSTEM, que tiene los privilegios necesarios para cambiar esa configuración.

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: