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 Que Revisa Si Existe Una Clave O Valor En El Registro

Posted by urpiano en Martes 2 \02\UTC enero \02\UTC 2007

VBScript nos permite, con el método RegRead del objeto wshShell, leer el contenido de un valor o del valor predeterminado de una clave. Si tan solo deseamos saber si existe no hay un método que haga esto, con lo que debemos solucionarlo con algo de programación, vamos a ver cómo lo podemos hacer.

La manera de hacer esto es usar On Error Resume Next antes de leer del registro, interceptar si se ha producido un error y de esa manera saber si la clave o valor existen. El script que aquí muestro nos permite pasarle dos parámetros, la ruta más nombre de la clave o valor y una booleana que en caso de ser True indica al script que se trata de una clave y en caso de ser False le indica que se trata de un valor. Ejemplo de llamada de una clave:

cscript //nologo existe-clave.vbs "HKCU\Software" True

Ejemplo de llamada de un valor:

cscript //nologo existe-clave.vbs "HKCU\Software\Google\machine_name" False

El script en sí no es más que un ejemplo, pues lo importante es la función f_LeeRegistro, que puede ser utilizada en cualquier otro script en la que la necesitemos. Tiene una debilidad, y es que se basa en la descripción para del error para poder evaluar si no existe una clave o si existe pero no tiene establecido el valor predeterminado. Por tanto, si necesitamos ejecutar el script en equipos con idiomas distintos del español, deberemos retocar la función para que busque lo correcto. Se podría revisar en qué idioma está el sistema y operar en conscuencia, pero eso hoy no toca -(|:oÞ

He aquí el script:

If Not f_LeeRegistro(WScript.Arguments(0),WScript.Arguments(1),var_Contenido) Then

    WScript.Echo "No existe la clave"

Else

    WScript.Echo "Contenido: " & var_Contenido

End If


Function f_LeeRegistro(str_Entrada, bol_Clave, var_Contenido)
'Esta función lee una clave o valor del registro. Recibe tres
'parámetros:

'    str_Entrada: Ruta y nombre de la clave o valor
'    bol_Clave: booleana que indica a la función si se trata
'               de una clave o un valor; seá una clave en el
'               el caso de que sea True
'    var_Contenido: variable que se usará de salida para obtener
'                   el contenido del valor o del valor
'                   predeterminado (en el caso de ser una clave)
'
'La devolución de la función es True en caso de existir o False en
'caso contrario


    'Si se trata de una clave nos aseguramos de que termina en
    'slash inverso ("")
    If bol_Clave _
    And Not (Right(str_Entrada,1) = "\") Then _
        str_Entrada = str_Entrada & "\"

    'Creamos un objeto wshShell
    Set obj_Shell = WScript.CreateObject("WScript.Shell")


    'Establecemos el salto a la siguiente línea en caso de error
    On Error Resume Next

    'Cargamos en la variable de salida el contenido del valor
    'o del valor predeterminado cuando se trata de una clave
    var_Contenido = obj_Shell.RegRead(str_Entrada)

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

        'Las clave que existen pero no tienen valor predeterminado
        'establecido dan error, por lo que debemos revisar
        'el error que se produjo
        If bol_Clave Then

             'Por desgracia el número de error es el mismo en el
             'caso de que no exista la clave o de que exista pero
             'no tenga establecido el valor predeterminado. Para
             'distinguir estos dos casos debemos revisar la 
             'descripción del error. Si no existe dirá "Raíz no
             'valida en la clave del registro....", mientras que
             'si existe pero no tiene establecido el valor
             'predeterminado la descripción es "No se pudo abrir
             'la clave del registro ... para leerla"
             If LCase(Left(Err.Description,4)) = "raíz" Then
    
                 f_LeeRegistro = False

             ElseIf LCase(Left(Err.Description,16)) = "no se pudo abrir" Then

                 f_LeeRegistro = True

             'Mostramos qué error inesperado se ha producido
             Else

                 WScript.Echo "Error " & Err.Number & ": " & _
                              Err.Description

             End If

             'Limpiamos el registro de error
             Err.Clear

        'Se ha producido error al leer un valor, por tanto no existe
        Else

            f_LeeRegistro = False

        End If

    'No se ha rpducido error, por tanto el valor o clave existe
    Else
        
        f_LeeRegistro = True

    End If
    
    'Nos limpiamos el culito :-)
    Set obj_Shell = Nothing

End Function

15 comentarios to “Script VBScript Que Revisa Si Existe Una Clave O Valor En El Registro”

  1. Jorge said

    Funciona perfectamente, de hecho lo incluí en un script para eliminar el WGA de Microsoft (los avisos que salen acerca de que se trata de una copia de windows ilegal). gracias Urpiano

  2. Cristian Rico said

    Una super pregunta…. como agrego al registro una clave ?? no un valor (en el regedit es una carpeta)….

    • urpiano said

      Cristian Rico,

      Agregar una clave es muy parecido a agregar un valor; su nombre debe terminar con \, para que se sepa que es una clave; además, puedes establecer su valor predeterminado al crearla:

      Set obj_Shell = WScript.CreateObject("WScript.Shell")
      obj_Shell.RegWrite "HKCU\Software\Mi Nueva Clave\", _
      "Este es su valor predeterminado"

  3. David Garcia said

    Quiero modificar la siguiente clave:
    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\USBSTOR
    Nombre: Start
    Valor: 4

    Mi problema es que no tengo credenciales a la hora de ejecutar el script de inicio, es posible pasar las credenciales de administrador como parametro?

    Muchas gracias

    • urpiano said

      David Garcia,

      En lugar de establecer el script como script de inicio de sesión, hazlo como script de inicio de equipo, con lo que el usuario que lo ejecuta es SYSTEM y no tendrás problemas de permisos. Date cuenta que el problema es que escribe en HKEY_LOCAL_MACHINE, que es una configuración de equipo, no de usuario, con lo que noes necesario que sea ejecutado en un script de logon.

  4. thaszck said

    oye una pregunta ami me sale estes error

    Raiz no valida en la clave del registro

    “HKLM\Software\Clients\StartMenuInternet\\shelf\open\command\”

    como lo puedo solucionar

    de antemano gracias..

    indiegente thaszck

  5. Aaron said

    me aparace este error se esperaba ‘)’ en linea 11 caracter 42

    Function f_LeeRegistro(HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Installer\Products\47529BC12F69B7647B39C5BE534CC092,t,var_Contenido)

    • urpiano said

      Aaron,

      ¿Has retocado el script de forma que en la declaración de la función pones la clave que quieres consultar y en lugar de True pones t?
      Debes dejar el script tal y como está y lanzarlo tal y como se indica:

      Para consultar una clave:

      cscript //nologo existe-clave.vbs “HKCU\Software” True

      Para soncultar un valor:

      cscript //nologo existe-clave.vbs “HKCU\Software\Google\machine_name” False

  6. hector said

    En mi caso yo requiero que dependiendo de un error que aparesca en el visor de sucesos de windows, se ejecute un scrip cada vez que esto suceda, como puedo hacerlo ?

  7. Julio Cesar said

    Saludos:

    Es muy bueno tu post, recientemente lo encontre y realiza la funcion q necesito, solo un pregunta dado q soy nuevo en esto de los scripts y no se me da muy bien, he intentado definir los valores dentro del script para que no sea necesario pasarle los valores, solo q no he podido hacerlo correctamente por q siempre q delcaro los valores dentro me marca error al ejecutarlo con doble clic. Me podrias decir de q manera se definen los valores dentro de tu script??

    • urpiano said

      Julio Cesar,

      No acabo de entender el no querer pasarle los valores como parámetro y sí querer ponerlos “hardcoded” lo que te obliga a retocar el script cada vez que quieras consultar una clave o valor distinto. En lugar de hacer doble clic sobre el script, debes lanzarlos desde una ventana de comandos, como indico en los dos ejemplos. Si quieres hacerlo “hardcoded”, debes modificar la primera línea:

      If Not f_LeeRegistro(WScript.Arguments(0),WScript.Arguments(1),var_Contenido) Then

      Te pongo esta primera línea con los dos ejemplos del post:

      If Not f_LeeRegistro("HKCU\Software",True,var_Contenido) Then
      If Not f_LeeRegistro("HKCU\Software\Google\machine_name",False,var_Contenido) Then
  8. Jackuap said

    Estimado,

    Me podrias ayudar con una duda en vbscript ya que he buscado en varios foros y no podido conseguir la respuesta, en una de esas estoy buscando mal

    Estoy sacando el mes del equipo consultando con el sistema operativo, pero cuando quiero pasar este valor de variable como nombre de directorio nuevo a crear me arroja un error y siendo que el path de donde quiero crear ya se encuentra creado

    dateInfo = Datepart(“yyyy” , Now) & Datepart(“m” , Now) & VbCrLf ‘Formato yyyymm ex 201011
    rutaComu = “D:\Concentrador\Comunicaciones\Logs\”
    Set objFolder = objFso.CreateFolder(rutaComu & dateInfo)

    Es decir, estoy tratando de crear el directorio 201011 en el siguiente path “rutaComu” de manera que quede así

    D:\Concentrador\Comunicaciones\Logs\201011

    pero cuando intento pasarle el nombre de la carpeta con variable me reclama..

    gracias

    • urpiano said

      Jackuap,

      Creo que te sobra el salto de línea, no puede poner un salto de línea en un nombre de carpeta. Además, tal y como lo haces, los meses de un solo dígito no estarán como, por ejemplo enero, 201001, si no que quedarán como 20101; para esto, hay un viejo truco, que es poner un cero delante del resultado y pasar la cadena a la función Right, poniendo 2 como longitud de la cadena resultante, lo que hace que si es de un dígito se pone el cero a la izquierda y si es de dos no. Por tanto, prueba así:

      Set objFSO = CreateObject("Scripting.FileSystemObject")
      dateInfo = Datepart("yyyy" , Now) & Right("0" & Datepart("m" , Now),2) 'Formato yyyymm ex 201011
      rutaComu = "C:\Concentrador\Comunicaciones\Logs\"
      Set objFolder = objFso.CreateFolder(rutaComu & dateInfo)
  9. When someone writes an post he/she retains the image of
    a user in his/her mind that how a user can be aware of it.

    So that’s why this piece of writing is outstdanding.
    Thanks!

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: