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…

VbScript: Script Para Obtener Un Listado HTML De Los Productos Instalados Con Windows Installer

Posted by urpiano en Jueves 24 \24\UTC noviembre \24\UTC 2011

Este script nos permite obtener un listado con los productos intalados con Windows Installer en el equipo (son aquellos que fueron instalados con un fichero MSI), es decir, las instancias de la clase Win32_Product de WMI que tengamos en el equipo donde ejecutemos este script. El listado que obtenemos es guardado en un fichero HTML como tabla, en la que podremos ver el producto y las propiedades que tengamos del mismo.

Sintaxis

cscript [//nologo] [ruta\]Win32_Product2HTML.vbs carpeta

Siendo

Etiqueta Dato ¿Requerido? Descripción
  carpeta
Carpeta en el que se generará el fichero HTML con los resultados. Puede ser un punto (lo que hará que se guarde en la carpeta donde esté ubicado el inductor de la ventana de comandos desde la que se lance el script), una ruta relativa (lo que permite especificar una carpeta a través del uso un punto o dos puntos seguidos, según se quiera hacer referencia a la carpeta actual o a la precedente) o también puede ser una ruta completa, tanto local como UNC. Si la ruta contiene uno o más espacios, es necesario encerrarla entre comillas.

Ejemplos:

– En este caso se almacenará en la carpeta en la que está el inductor de la ventana de comandos:

cscript //nologo c:\scripts\Win32_Product2HTML.vbs .

– En este caso se almacenará en la carpeta precedente a la que está el inductor de la ventana de comandos:

cscript //nologo c:\scripts\Win32_Product2HTML.vbs ..

– En este caso se almacenará en la carpeta Listados que está en la carpeta precedente a la que está el inductor de la ventana de comandos:

cscript //nologo c:\scripts\Win32_Product2HTML.vbs ..\Listados

– En este caso se almacenará en la carpeta local d:\Listados\WMI:

cscript //nologo c:\scripts\Win32_Product2HTML.vbs d:\Listados\WMI

– En este caso se almacenará en la carpeta de red \\servidor\carpetaOculta$\Listados WMI:

cscript //nologo c:\scripts\Win32_Product2HTML.vbs "\\servidor\carpetaOculta$\Listados WMI"

Este es el código del script

Option Explicit

Dim obj_ServicioWMI
Dim col_Productos
Dim obj_Producto
Dim obj_SH
Dim obj_ST
Dim obj_FS
Dim int_Total
Dim str_Valor
Dim int_Valor
Dim str_Ruta
Dim str_Equipo
Dim str_Fecha
Dim dth_Fecha

'Constantes para ADODB.Stream
Const adTypeBinary          = 1
Const adTypeText            = 2
Const adSaveCreateNotExist  = 1
Const adSaveCreateOverWrite = 2

'Obtenemos la ruta desde el parámetro, si ha sido pasado
If WScript.Arguments.Count > 0 Then

    str_Ruta = WScript.Arguments(0)
    
Else

    'El parámetro no se recibió: avisamos al usuario y terminamos el script
    'con código de salida 68686868 (69696969 y te debo 1010101)
    WScript.Echo "Carpeta de destino no pasada. Éste es un parámetro requerido"
    WScript.Echo ""
    WScript.Echo "Usar:"
    WScript.Echo "cscript Win32_Product2HTML.vbs \\servidor\carpeta\subcarpeta"
    WScript.Echo "cscript Win32_Product2HTML.vbs ""d:\carpeta inventario"""
    WScript.Quit 68686868
    
End if

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

'Si no existe la carpeta
If Not obj_FS.FolderExists(str_Ruta) Then
    
    'Advertimos la no existencia de la carpeta al usuario
    WScript.Echo "La carpeta especificada no existe"
    'salimos del script con la salida 69696969 :oP
    WScript.Quit 69696969
    
End If

'Una vez comprobada la existencia de la carpeta destruimos el objeto
'FileSystemObject
Set obj_FS = Nothing

'Nos aseguramos de que la ruta de la carpeta termina en slash inverso
If Right(str_Ruta,1) <> "\" Then str_Ruta = str_Ruta & "\"

'Obtenemos la fecha
dth_Fecha = Now()
'Obtenemos la fecha en formato YYYYMMDD y le ponemos un guión bajo al final
str_Fecha = Year(dth_Fecha) & _
            Right("00" & Month(dth_Fecha), 2) & _
            Right("00" & Day(dth_Fecha), 2) & _
            "_"

'Creamos un objeto Shell, para poder acceder a las variables de entorno
Set obj_SH = CreateObject("WScript.Shell")

'Creamos un objeto ADODB.Stream para poder codificar el fichero con los
'resultados en UTF-8
Set obj_ST = CreateObject("ADODB.Stream")

'Abrimos el Stream
obj_ST.Open

'Establecemos la codificación del Stream como UTF-8
obj_ST.Charset = "utf-8"

'Establecemos que trabajaremos con texto
obj_ST.Type = adTypeText

'Obtenemos el nombre del equipo en el que se está ejecutando el script
str_Equipo = obj_SH.ExpandEnvironmentStrings("%COMPUTERNAME%")

'Iniciamos el contador de productos
int_Total = 0

'Ponemos los encabezados al documento HTML que vamos a ir montando
obj_ST.WriteText "<!DOCTYPE html PUBLIC ""-//W3C//DTD XHTML 1.0 Transition" & _
                 "al//EN"" ""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transi" & _
                 "tional.dtd"">" & vbCrLf
obj_ST.WriteText "<html>" & vbCrLf
obj_ST.WriteText "<head>" & vbCrLf
'Ponemos el título
obj_ST.WriteText "  <title>Productos Instalados en el equipo " & str_Equipo & _
                 "</title>" & vbCrLf
'Establecemos la codificación UTF-8
obj_ST.WriteText "  <meta http-equiv=""Content-Type"" content=""text/html;" & _
                 " charset=utf-8"" />" & vbCrLf
'Creamos una hoja de estilo
obj_ST.WriteText "  <style type=""text/css"">" & vbCrLf
'este estilo es para los nombres de las instancias
obj_ST.WriteText "    .nombre_instancia{background-color:#4bacc6;font:10pt" & _
                 " Tahoma;font-weight:bold;color:#ffffff}" & vbCrLf
'Este estilo para los encabezados (donde pone "Nombre de propiedad | Valor"
obj_ST.WriteText "    .encabezado{background-color:#8b3331;font:8pt Tahoma" & _
                 ";color: #ffffff;font-weight: bold;}" & _
                 vbCrLf
'Este estilo para los nombres de las propiedades (primera columna)
obj_ST.WriteText "    .nombre_propiedad{background-color:#c0504d;font:10pt" & _
                 " Tahoma;color: #ffffff;font-weight: bold;}" & _
                 vbCrLf
'Los valores los pondremos bandeados, es decir, una fila de un color, otra de
'otro.
'Este estilo es el color 1
obj_ST.WriteText "    .valor1{background-color:#e6b9b8;font:10pt Tahoma;}" & _
                 vbCrLf
'Este estilo es el color 2
obj_ST.WriteText "    .valor2{background-color:#f2dddc;font:10pt Tahoma;}" & _
                 vbCrLf
obj_ST.WriteText "  </style>" & vbCrLf
obj_ST.WriteText "</head>" & vbCrLf
obj_ST.WriteText "<body>" & vbCrLf
'Iniciamos la tabla con los resultados
obj_ST.WriteText "<table border=""1"">" & vbCrLf

'Conectamos a WMI
Set obj_ServicioWMI = GetObject("winmgmts:\\" & str_Equipo & "\root\cimv2")
'Obtenemos los productos instalados
Set col_Productos = obj_ServicioWMI.ExecQuery("SELECT * FROM Win32_Product",,48)

'Vamos a establecer "control" de errores, porque dependiendo de la versión
'de Windows, la clase tendrá o no determinadas propiedades, por ello, si
'no existe una propiedad, de esta manera podremos saltarnos su línea
On Error Resume Next

For Each obj_Producto in col_Productos

    'Incrementamos el contador de productos
    int_Total = int_Total + 1
    'Ponemos el nombre del producto
	obj_ST.WriteText "<tr><td class=""nombre_instancia"" colspan=""2"">" & _
	                 obj_Producto.Caption & "</td></tr>" & vbCrLf
	'Ponemos el encabezado
	obj_ST.WriteText "<tr class=""encabezado""><td>Nombre de Propiedad" & _
	                 "</td><td>Valor</td></tr>" & vbCrLf
	obj_ST.WriteText "<tr><td class=""nombre_propiedad"">AssignmentType</td><" & _
                     "td class=""" & f_EstiloValor & """>" & _
	                 obj_Producto.AssignmentType & "</td></tr>" & vbCrLf
	'Establecemos el contador de propiedades a 1
	int_Valor = 1
	'Establecemos el estilo del valor como valor1
	str_Valor = "valor1"
	'Escribimos la primera propiedad con el estilo definido en str_Valor
	obj_ST.WriteText "<tr><td class=""nombre_propiedad"">Caption</td><td clas" & _
                     "s=""" & f_EstiloValor & """>" & _
	                 obj_Producto.Caption & "</td></tr>" & vbCrLf
    'Para el resto de propiedades pondremos como estilo la devolución de la
    'función f_EstiloValor (siempre será "valor1" o "valor2")
	obj_ST.WriteText "<tr><td class=""nombre_propiedad"">Description</td><td " & _
                     "class=""" & f_EstiloValor & """>" & _
	                 obj_Producto.Description & "</td></tr>" & vbCrLf
	obj_ST.WriteText "<tr><td class=""nombre_propiedad"">HelpLink</td><td cla" & _
                     "ss=""" & f_EstiloValor & """>" & _
	                 obj_Producto.HelpLink & "</td></tr>" & vbCrLf
	obj_ST.WriteText "<tr><td class=""nombre_propiedad"">HelpTelephone</td><t" & _
                     "d class=""" & f_EstiloValor & """>" & _
	                 obj_Producto.HelpTelephone & "</td></tr>" & vbCrLf
	obj_ST.WriteText "<tr><td class=""nombre_propiedad"">IdentifyingNumber</t" & _
                     "d><td class=""" & f_EstiloValor & """>" & _
	                 obj_Producto.IdentifyingNumber & "</td></tr>" & vbCrLf
	obj_ST.WriteText "<tr><td class=""nombre_propiedad"">InstallDate</td><td " & _
                     "class=""" & f_EstiloValor & """>" & _
	                 obj_Producto.InstallDate & "</td></tr>" & vbCrLf
	obj_ST.WriteText "<tr><td class=""nombre_propiedad"">InstallDate2</td><td" & _
                     " class=""" & f_EstiloValor & """>" & _
	                 obj_Producto.InstallDate2 & "</td></tr>" & vbCrLf
	obj_ST.WriteText "<tr><td class=""nombre_propiedad"">InstallLocation</td>" & _
                     "<td class=""" & f_EstiloValor & """>" & _
	                 obj_Producto.InstallLocation & "</td></tr>" & vbCrLf
	obj_ST.WriteText "<tr><td class=""nombre_propiedad"">InstallSource</td><t" & _
                     "d class=""" & f_EstiloValor & """>" & _
	                 obj_Producto.InstallSource & "</td></tr>" & vbCrLf
	obj_ST.WriteText "<tr><td class=""nombre_propiedad"">InstallState</td><td" & _
                     " class=""" & f_EstiloValor & """>" & _
	                 obj_Producto.InstallState & "</td></tr>" & vbCrLf
	obj_ST.WriteText "<tr><td class=""nombre_propiedad"">Language</td><td cla" & _
                     "ss=""" & f_EstiloValor & """>" & _
	                 obj_Producto.Language & "</td></tr>" & vbCrLf
	obj_ST.WriteText "<tr><td class=""nombre_propiedad"">LocalPackage</td><td" & _
                     " class=""" & f_EstiloValor & """>" & _
	                 obj_Producto.LocalPackage & "</td></tr>" & vbCrLf
	obj_ST.WriteText "<tr><td class=""nombre_propiedad"">Name</td><td class=" & _
                     """" & f_EstiloValor & """>" & _
	                 obj_Producto.Name & "</td></tr>" & vbCrLf
	obj_ST.WriteText "<tr><td class=""nombre_propiedad"">PackageCache</td><td" & _
                     " class=""" & f_EstiloValor & """>" & _
	                 obj_Producto.PackageCache & "</td></tr>" & vbCrLf
	obj_ST.WriteText "<tr><td class=""nombre_propiedad"">PackageCode</td><td " & _
                     "class=""" & f_EstiloValor & """>" & _
	                 obj_Producto.PackageCode & "</td></tr>" & vbCrLf
	obj_ST.WriteText "<tr><td class=""nombre_propiedad"">PackageName</td><td " & _
                     "class=""" & f_EstiloValor & """>" & _
	                 obj_Producto.PackageName & "</td></tr>" & vbCrLf
	obj_ST.WriteText "<tr><td class=""nombre_propiedad"">ProductID</td><td cl" & _
                     "ass=""" & f_EstiloValor & """>" & _
	                 obj_Producto.ProductID & "</td></tr>" & vbCrLf
	obj_ST.WriteText "<tr><td class=""nombre_propiedad"">RegCompany</td><td c" & _
                     "lass=""" & f_EstiloValor & """>" & _
	                 obj_Producto.RegCompany & "</td></tr>" & vbCrLf
	obj_ST.WriteText "<tr><td class=""nombre_propiedad"">RegOwner</td><td cla" & _
                     "ss=""" & f_EstiloValor & """>" & _
	                 obj_Producto.RegOwner & "</td></tr>" & vbCrLf
	obj_ST.WriteText "<tr><td class=""nombre_propiedad"">SKUNumber</td><td cl" & _
                     "ass=""" & f_EstiloValor & """>" & _
	                 obj_Producto.SKUNumber & "</td></tr>" & vbCrLf
	obj_ST.WriteText "<tr><td class=""nombre_propiedad"">Transforms</td><td c" & _
                     "lass=""" & f_EstiloValor & """>" & _
	                 obj_Producto.Transforms & "</td></tr>" & vbCrLf
	obj_ST.WriteText "<tr><td class=""nombre_propiedad"">URLInfoAbout</td><td" & _
                     " class=""" & f_EstiloValor & """>" & _
	                 obj_Producto.URLInfoAbout & "</td></tr>" & vbCrLf
	obj_ST.WriteText "<tr><td class=""nombre_propiedad"">URLUpdateInfo</td><t" & _
                     "d class=""" & f_EstiloValor & """>" & _
	                 obj_Producto.URLUpdateInfo & "</td></tr>" & vbCrLf
	obj_ST.WriteText "<tr><td class=""nombre_propiedad"">Vendor</td><td class" & _
                     "=""" & f_EstiloValor & """>" & _
	                 obj_Producto.Vendor & "</td></tr>" & vbCrLf
	obj_ST.WriteText "<tr><td class=""nombre_propiedad"">Version</td><td clas" & _
                     "s=""" & f_EstiloValor & """>" & _
	                 obj_Producto.Version & "</td></tr>" & vbCrLf
	obj_ST.WriteText "<tr><td class=""nombre_propiedad"">WordCount</td><td cl" & _
                     "ass=""" & f_EstiloValor & """>" & _
	                 obj_Producto.WordCount & "</td></tr>" & vbCrLf
Next

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

'Cerramos la tabla, el cuerpo y el documento HTML
obj_ST.WriteText "</table>" & vbCrLf
obj_ST.WriteText "<h3>Nodo: " & str_Equipo & " - " & int_Total & _
                 " Instancias de Win32_Product</h3>" & vbCrLf
obj_ST.WriteText "</body>" & vbCrLf
obj_ST.WriteText "</html>"

'Guardamos el documento HTML en la ruta recibida como parámetro y con el nombre
'de equipo seguido de Poduct.html
obj_ST.SaveToFile obj_SH.ExpandEnvironmentStrings(str_Ruta & str_Fecha & _
                                             "%COMPUTERNAME%_Products.html"), _
                                             adSaveCreateOverWrite

Function f_EstiloValor()
'Esta función devuelve el estilo a aplicar en el momento presente. Se basa en
'el valor que tenga el estilo de la propiedad actual. Para ello se han definido
'dos propiedades a nivel de script:
'
'    - int_Valor: que almacena el número de propiedad válido último que había
'                 (es decir, que sólo se incrementa en el caso de que la
'                  propiedad exista en la instancia)
'    - str_Valor: es el nombre de estilo CSS (puede ser únicamente valor1 y
'                 valor2)
'
'´Para realizar su cometido, la función revisa si se ha producido algún error,
'en caso negativo incrementará el valor de int_Valor y calculará si el estilo
'es el uno o el dos, sustrayendo dos el resto de la división entera de
'int_Valor entre dos; esto quiere decir que si int_Valor es impar, se restará
'1 a 2 y por tanto el resultado será 1 (el estilo será valor1); si int_Valor es
'par se restará 0 a 2 y por tanto el resultado será 2 (el estilo será valor2)
	
	'Si no hay errores
	If Err.Number = 0 Then
	
	   'Incrementamos el valor de int_Valor
	   int_Valor = int_Valor + 1
	   'Calculamos el estilo
	   str_Valor = "valor" & (2 - (int_Valor Mod 2))
	   
	Else
	
	   'Se ha producido error. Lo único que hacemos el limpiar el objeto de
	   'errores preparando la siguiente llamada
	   Err.Clear
	   
	End If
	
	'Se devuelve el estilo
	f_EstiloValor = str_Valor

End Function

2 comentarios to “VbScript: Script Para Obtener Un Listado HTML De Los Productos Instalados Con Windows Installer”

  1. […] VbScript: Script Para Obtener Un Listado HTML De Los Productos Instalados Con Windows Installer […]

  2. […] "jqmodal", embeddedHeight: "400", embeddedWidth: "425", themeCSS: "" }); . VbScript: Script Para Obtener Un Listado HTML De Los Productos … . Script VbScript para […]

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: