Cambiar el Registro con scripts: Windows Script Host

El scripting parece la herramienta final en el control y automatización de Windows. No son archivos de lotes, son programas administrativos con todas las de la ley qué, considerando la riqueza de poder de lo que son capaces, son sorpresivamente fáciles de crear. Podemos escribir un script que realice un inventario de un equipo y guarde el resultado en un archivo de la red, por ejemplo. Automatizar una aplicación para que realice pasos repetitivos automáticamente. Las posibilidades son grandes la verdad, pero vamos a ver cómo usarlos para editar el Registro.

La técnica de WSH es la tecnología de scripting de Windows. Con un simple script podemos conocer las distintas versiones que tenemos instaladas, Conocer_version_script.

* Por supuesto, el uso de WMI es una alternativa de edición del Registro al uso de VBscript.

Los Scripting Guys han creado Tweakomatic para crear scripts por nosotros, y que nos servirá para modificarlos según nos convenga.

También se dispone, entreo otros muchos, de un sitio web donde hay cantidad de info y de scripts diversos: Script Center.

Vamos con los script

Los archivos de script pueden tener diferentes extensiones y con ellas indicar que tipo de lenguaje contienen. La extensión .js contienen JScript, la *.vbs VBScript. Aunque al fin y al cabo, son archivos de texto conteniendo las palabras clave del lenguaje elegido, por ello podemos crear scripts desde el bloc de notas simplemente. Eso sí, hay que asegurarse al momento de guardarlos de la extensión que se le añade e impedir que el bloc añada la txt predefinidamente.

Accederemos al Registro mediante el objeto Shell. Este objeto contiene los métodos que llamaremos para añadir, quitar y actualizar valores en el Registro. Añadiremos la siguiente declaración de código en cada script que queremos que acceda al Registro, la primera línea muestra como crear un objeto SHELL con VBScript y la segunda como hacerlo con JScript.

set WshShell = WScript.CreateObject(«WScript.Shell»)

var WshShell = WScript.CreateObject(«WScript.Shell»);

No es díficil crear un script, se abre el bloc de notas y se escribe un contenido, por ejemplo:

var WshShell = WScript.CreateObject("WScript.Shell");
WshShell.Popup("Esto es un script con JScript");

JScript es sensible a mayúsculas y minúsculas, cuidado al escribir, VBScript tiene el beneficio de lo contrario, no las distingue. Guardamos el ejemplo con el bloc de notas con la extensión .js y lo probamos.

jscript01

Normalmente para trabajar con el Registro lo hacemos con archivos INF, o con archivos de lotes con Reg.exe, por su simplicidad, pero hay veces que el método idóneo es mediante un script: cuando necesitamos un interfaz de usuario, si queremos mostrar o reunir configuraciones de usuarios, y además es el único que nos da acceso completo a Windows.

Combinado con WMI es increible.

   1: '*inventario de equipo*

   2: strComputer = "."

   3:  

   4: Set objWMIService = GetObject("winmgmts:{impersonationlevel=impersonate}!\" & strComputer & "rootcimv2")

   5: Set colsettings = ObjWMIService.ExecQuery ("Select * from Win32_OperatingSystem")

   6:  

   7: For Each objOperatingSystem in colsettings

   8:     Wscript.Echo "********************" & VbCrlf & _

   9:     "SISTEMA" & VbCrlf & "********************" & VbCrlf & _

  10:     "Nombre Sistema: " & objOperatingSystem.Name & VbCrlf & _

  11:     "Versión Sistem: " & objOperatingSystem.Version & VbCrlf & _

  12:     "Services Packs: " & objOperatingSystem.ServicePackMajorVersion & "." & objOperatingSystem.ServicePackMinorVersion & VbCrlf & _

  13:     "Nombre Creador: " & objOperatingSystem.Manufacturer & VbCrlf & _

  14:     "Dir.   Windows: " & objOperatingSystem.WindowsDirectory & VbCrlf & _

  15:     "Confg.  Local : " & objOperatingSystem.Locale & VbCrlf & _

  16:     "Memoria Físic.: " & objOperatingSystem.FreePhysicalMemory & VbCrlf & _

  17:     "Memoria Virtu.: " & objOperatingSystem.TotalVirtualMemorySize & VbCrlf & _

  18:     "Mem. Vir. dis.: " & objOperatingSystem.FreeVirtualMemory & VbCrlf & _

  19:     "Paginamiento  : " & objOperatingSystem.SizeStoredInPagingFiles

  20: Next

  21: Set colsettings = ObjWMIService.ExecQuery ("Select * from Win32_ComputerSystem")

  22:  

  23: For Each objComputer in colsettings

  24:     Wscript.Echo "********************" & VbCrlf & "EQUIPO" & VbCrlf & "********************" & VbCrlf & _

  25:      "Nombre Equipo : " & objComputer.Name & VbCrlf & _

  26:      "Const. Equipo : " & objComputer.Manufacturer & VbCrlf & _

  27:      "Modelo Equipo : " & objComputer.Model & VbCrlf & _

  28:      "Zona horaria  : " & objComputer.CurrentTimeZone & VbCrlf & _

  29:      "Memoria física: " & objComputer.TotalPhysicalMemory

  30: Next

  31:  

  32: Set colsettings = ObjWMIService.ExecQuery ("Select * from Win32_Processor")

  33:  

  34: For Each objProcessor in colsettings

  35:     Wscript.Echo "********************" & VbCrlf & "PROCESADOR" & VbCrlf & "********************" & VbCrlf & _

  36:      "Tipo Proc.  : " & objProcessor.Architecture & VbCrlf & _

  37:      "Descripción : " & objProcessor.Description

  38: Next

  39:  

  40: Set colsettings = ObjWMIService.ExecQuery ("Select * from Win32_BIOS")

  41:  

  42: For Each objBIOS in colsettings

  43:     Wscript.Echo "********************" & VbCrlf & "BIOS" & VbCrlf & "********************" & VbCrlf & objBIOS.Version

  44: Next

Ejecutando scripts

Windows proporciona dos scripting hosts (si no contamos powershell), los basados en Windows que se ejecutan con doble-clic en el archivo de script, cuyo motor es WScript.exe y la versión de línea de comandos, que es práctico cuando el script proporciona una salida de datos similar a la que dan la mayoría de programas de línea de comandos y cuyo motor es Cscript.exe. El ejemplo anterior puede probarse en ambos motores y ver la diferencia.

cscript01

En línea de comandos se dispone de la sintaxis siguiente:

cscript archivo_script [//B|//I] [//D] [//E:motor] [//H:cscript|//H:wscript] [//Job:trabajo] [//Logo|//NoLogo] [//S] [//T:tiempo] [//X] [//?]

 

//B Modo por lotes: no muestra alertas, ni errores ni solicita entradas.
//I Modo interactivo: muestra las alertas, los errores y solicita entradas, modo predeterminado y contrario al //B.
//D Conecta el depurador.
//E:motor Especifica el lenguaje de script que se usa para su ejecución.
//H:cscript
//H:wscript
Registra el host predeterminado de ejecución de scripts, si no se especifica es Wscript.exe
//Job:trabajo Ejecuta el trabajo identificado como trabajo en un archivo .wsf
//Logo Especifica que el banner de Windows Script Host se muestre en la ventana de consola antes de ejecutar el script. Predeterminado.
//NoLogo Contrario a //Logo, el banner no se muestra.
//S Guarda las opciones de línea de comando actuales para el usuario actual.
//T:tiempo Tiempo máximo de ejecución del script en segundos. Se puede especificar un máximo de 32767 segundos y de forma predeterminada no hay límite.
//X Inicia el script en el depurador.
//? Muestra los parámetros del comando disponibles y ofrece ayuda para su uso. (Mismo resultado escribiendo cscript.exe si parámetros ni archivos de script)

Podemos especificar alguna de las opciones también para los basados en Windows. Clic derecho sobre el script y Propiedades, pestaña secuencia de comandos (Script en algunos casos):

cscript02

Tiempo permitido de ejecución y si se muestra o no un log. El resultado de modificarlo es un acceso directo al script con la extensión .wsh desde el que ejecutaremos el script.

Formato de nombres de clave y valores

El formato de los nombres de claves y valores en un script tiene una simple regla: si una cadena acaba con una barra invertida es un nombre de clave, sino, es un nombre de valor. En jscript, el caracter de barra invertida está reservado como caracter escape, como n es el de nueva línea y t una tabulación, por ello si hemos de utilizar la barra invertida la pondremos doble.

  VBScript JScript
Valor «HKLMsubclavevalor» «HKLM\subclave\valor»
Clave «HKLMsubclave» «HKLM\subclave\»

Añadir y actualizar valores

El método RegWrite del objeto shell añade claves y valores o cambia valores existentes. Si queremos cambiar un valor predeterminado de una clave, establecemos la variable strNombre al nombre de la clave, incluyendo las barras invertidas y entonces establecemos un valor sobre él.

object.RegWrite ( strNombre, valor [, strTipo])

object es el objeto shell.

strNombre es la cadena que indica el nombre de la clave o valor y debe comenzar por una de las claves raíz: HKCR, HKCU, HKLM o HKU.

valor es el dato a asignar al valor nuevo o existente con el formato apropiado al tipo de valor.

strTipo es el tipo de valor a crear: REG_SZ, REG_EXPAND_SZ, etc… Teniendo en cuenta que RegWrite no es compatible con el REG_MULTI_SZ y que en valores REG_BINARY sólo escribe 4-bits.

VBScript

JScript

Set WshShell = WScript.CreateObject(«Wscript.Shell»)
WshShell.RegWrite «HKCUSoftwareEj», 1, «REG_BINARY»
WshShell.RegWrite «HKCUSoftwareEjHola», «Hola», «REG_SZ»
var WshShell = WScript.CreateObject(«Wscript.Shell»);
WshShell.RegWrite («HKCU\Software\Ej\», 1, «REG_BINARY»);
WshShell.RegWrite («HKCU\Software\Ej\Hola», «Hola», «REG_SZ»);

Eliminar claves y valores

En este caso el método es RegDelete. Hay que ir con tiento. Eliminar una clave entera es fácil. Si la cadena strNombre acaba con barra invertida es una clave, sino, es un valor.

object.RegDelete ( strNombre)

Consultar valores

El método de consulta es RegRead, que devuelve el dato de un valor. Valor predeterminado de la clave si acaba con barra invertida, en otro caso datos del valor.

object.RegRead ( strNombre)

Cambiar el Registro con scripts: Archivos REG

Como se ha visto en algún otro artículo, podmos crear archivos REG con el Editor del Registro (Regedit.exe). Estos archivos son el método más clásico para añadir, y cambiar valores en el Registro, aunque no sea tan potente como otros métodos que vamos viendo. La mayor fragilidad de los REG es que no podemos usarlos para quitar valores, sólo añadirlos o modificarlos y en todo caso, eliminar llaves.

En cuanto hemos creado un REG, lo podemos importar al Registro con un simple doble-clic. Es un método agradable si queremos que se importe manualmente, sea por nosotros o por nuestros usuarios, pero necesitaremos el uso del comando regedit /s archivo.reg si queremos importarlo mediante una infraestructura de administración de software o proporcionando un enlace en la intranet. Donde sustituimos archivo.reg por el archivo a importar, incluído su ruta. La opción /s lo importa sin preguntar nada al usuario. Recuerda! para editarlo, clic derecho y editar, un doble-clic no lo abrirá en el bloc de notas sino que lo importará directamente al Registro.

Hay dos tipos distintos de archivos REG, la versión 4 es ANSI y la versión 5 es Unicode. Ante la duda, crearlo siempre en version 5.

La manera más fácil de crear un REG es con RegEdit, exportando las claves.

Sin embargo, también podemos crearlos de forma manual, aunque ello supone un proceso propenso a la generación de errores no demasiado recomendable.

Abrimos el Bloc de notas y creamos un nuevo archivo:

  1. Al inicio añadimos uno de los dos seguido de una línea en blanco: si es versión 4 REGEDIT4 y si es versión 5 Windows Registry Editor Version 5.00.
  2. Cada clave de la que queremos importar valore, añadimos una sección tipo [Clave], donde Clave es el nombre completo qualificado de la clave, nada de abreviaturas.
  3. Cada valor a importar al Registro, añadimos el valor con el formato “nombre”=valor dentro de la sección de la [Clave]. Usa @ para un valor predeterminado de la clave. Cumplir con el formato del valor *, la barra invertida sirve de continuación de línea.
  4. Una vez terminado, Guardar como, escribimos su nombre y la extensión REG, asegurándonos que el Bloc de notas no le añade la extensión .txt, y entonces desde la lista desplegable CODIFICACIÓN escogemos ANSI para la version 4 y Unicode en el caso de versión 5.

codificacion

*formato de valores archivos REG

Tipo valor Versión 4 Versión 5
REG_SZ "string" "string"
REG_DWORD dword:00007734 dword:00007734
REG_BINARY hex:00,00,01,03 hex:00,00,01,03
REG_EXPAND_SZ hex(2):25, 53, 59, 53, 54, 45, 4d, 52, 4f, 4f, 54, 25, 00 hex(2):25, 00, 53, 00, 59, 00, 53, 00, 54, 00, 45, 00, 4d, 00, 52, 00, 4f, 00, 4f, 00, 54, 00, 25, 00, 00, 00,
REG_MULTI_SZ hex(7):25, 53, 59, 53, 54, 45, 4d, 52, 4f, 4f, 54, 25, 00, 25, 53, 59, 53, 54, 45, 4d, 52, 4f, 4f, 54, 25, 65, 00,00 hex(7):25, 00, 53, 00, 59, 00, 53, 00, 54, 00, 45, 00, 4d, 00, 52, 00, 4f, 00, 4f, 00, 54, 00, 25, 00, 00, 00, 25, 00, 53, 00, 59, 00, 53, 00, 54, 00, 45, 00, 4d, 00, 52, 00, 4f, 00, 4f, 00, 54, 00, 25, 00, 65, 00, 00, 00, 00, 00

Caracteres especiales en archivos REG

Dentro de los REG hay algunos caracteres que tienen un significado especial. Las comillas comienzan y terminan cadenas. La barra invertida indica continuación de línea. ¿Cómo podemos introducir estos caracteres en los valores? Pues usando como prefijo otra barra invertida. Con ello obtenemos:

\ represente a , por ejemplo: C:\archivos de programa\msoffice

" represente a ", por ejemplo: " esto es una cadena entre comillas"

n es una linea nueva

r es un retorno de carro.

Eliminar claves mediante REGs

No podemos eliminar valores individuales con archivos REG, pero si eliminar una clave entera. Tan sólo debemos preceder, usar como prefijo, el signo menos – a la clave a eliminar. Por ejemplo:

Windows Registry Editor Version 5.00

[-HKEY_CURRENT_USERSoftwareESET]

Un tip sencillo es primero exportar las claves a un REG, quitar sus valores y otras claves, ponerle el – a los nombres a eliminar e importarlo.