Introducción
Siguiendo con el “pequeño curso” de programación en VBS, veremos los conceptos básicos de WMI. Antes de arrancar, recomiendo a toda persona que esté empezando con el tema de scripting la lectura del artículo anterior “Introducción a VBS (Visual Basic Script)”.
Bueno, primero vamos a repasar un poquito qué es y para qué sirve WMI luego nos adentraremos en la programación.
WMI – La administración al alcance de las manos
WMI es la infraestructura en la que se basa la administración de sistemas operativos Microsoft (implementada a partir de Windows 2000 Professional SP2 y Windows 2000 Server). Nos permite realizar no solo la administración de los sistemas operativos sino también de los productos instalados (especialmente en productos Enterprise), a través de tareas automáticas y scripts.
Arquitectura
WMI provee una interfaz uniforme para cualquier script corra tanto local como remotamente. Esto quiere decir que no necesita llamar a una gran cantidad de APIs para operar.
.gif)
1- WMI Providers and Managed Objects: Los “WMI Providers” son objetos COM que monitorean uno o más “Managed Objects”. Un “Managed Object” es básicamente un componente lógico o físico (un disco rígido, una placa de red, el sistema operativo) que está representado como una instancia de Clases WMI. Ahora bien, ¿cómo realiza el manejo de estos componentes? el tema es así, cada “WMI Provider” tiene una DLL asociada y un archivo MOF (Managed Object Format) que definen las clases utilizables. Los archivos MOF y las DLL se encuentran guardadas dentro de la carpeta %WINDIR%\System32\Wbem.
2- WMI Infraestructure: Posee dos componentes:
· WMI service (winmgmt), incluyendo el WMI Core (núcleo)
· WMI repository: El WMI repository está organizado en “Namespaces” (ese es un concepto importante que nos va a servir en el futuro). Por defecto. El Servicio de WMI crea algunos namespaces como ser, root\default, root\cimv2, y root\subscription. Estos contienenen una serie de definiciones de clases incluyendo a las principales Win32 Classes, la WMI System Classes entre otras. Como nombramos anteriormente, los otros namespace son creados por otros WMI Providers.
3- WMI management applications and scripts: Esta sección se refiere a las aplicaciones (scripts) que interactúan con el “WMI Infraestructure" para correr queries, enumerar información, utilizar métodos o eventos.
Ejemplo
Bueno, después de tanta explicación teórica, es hora de plasmar todos esos conceptos en un ejemplo. Lo que vamos a hacer, es obtener el nombre del equipo en donde corremos el script:
'---------------------------------------------------------------------------------------------------------------
strComputer = "." 'Al asignar la variable a un punto (.) nos referimos al equipo local, el donde corremos el script
Set objWMIService = GetObject _
("winmgmts:\\" & strComputer & "\root\cimv2") 'Utilizamos el namespace \root\cimv2.
Set colItems = objWMIService.ExecQuery _
("Select * from Win32_ComputerSystem") 'Hacemos un query de la clase Win32_ComputerSystem e instanciamos una colección con esos datos.
For Each objItem in colItems
Wscript.Echo "Computer Name: " & objItem.Name 'Imprimimos por pantalla el nombre de equipo
Next
'---------------------------------------------------------------------------------------------------------------
Providers, Managed Objects, Namespace y Clases
A esta altura seguramente muchos de ustedes estarán diciendo “todo muy lindo, pero cómo se que Provider, namespace o clase utilizar si quiero…”, bueno, lamentablemente eso lo da la práctica y a decir verdad es casi imposible aprender de memoria todo así que en los anexos les estoy dejando una pequeña guía de referencia como para que tengan algo (después depende de ustedes seguir investigando) y adicionalmente les dejo tres scripts para verificar los providers, namespaces y clases existentes en el equipo.
A programar!!
Y si, llegó el momento de ponernos a programar un poco. Como seguramente las necesidades de cada uno de ustedes es diferente, voy a poner un par de “trucos” que les serán útiles en el futuro.
Manejo de archivos
VBS al ser un lenguaje reducido no posee la posibilidad de leer y escribir al mismo tiempo, o leemos o escribimos. Entonces, ¿Cómo hacemos para modificar un valor dentro de un archivo de texto? La respuesta es sencilla, aunque no es posible buscar y reemplazar texto directamente dentro de un archivo de texto, se puede hacer lo siguiente: 1) abrir un archivo de texto; 2) leer el texto en una variable; 3) realizar una búsqueda con sustitución en esa variable; y 4) volver a grabar el archivo de texto.
'---------------------------------------------------------------------------------------------------------------
Const ForReading = 1
Const ForWriting = 2
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("C:\Scripts\Nombres.txt", ForReading)
strText = objFile.ReadAll
objFile.Close
strNewText = Replace(strText, "Javier ", "Andrés ")
Set objFile = objFSO.OpenTextFile("C:\Scripts\Text.txt", ForWriting)
objFile.WriteLine strNewText
objFile.Close
'---------------------------------------------------------------------------------------------------------------
Vamos a ver otro ejemplo sencillo de manejo de archive, en este caso listaremos la cantidad de archivos que hay en una carpeta.
'---------------------------------------------------------------------------------------------------------------
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colFileList = objWMIService.ExecQuery _
("ASSOCIATORS OF {Win32_Directory.Name='C:\TestLog'} Where " _
& "ResultClass = CIM_DataFile")
If colFileList.Count = 0 Then
Wscript.Echo "No hay archivos en la carpeta."
Else
Wscript.Echo "Hay " & colFileList.Count & " en la carpeta"
End If
'---------------------------------------------------------------------------------------------------------------
Conclusión
Estuvimos viendo un panorama de lo que es WMI, para que sirve y cuales son sus componentes. Para la próxima, nos adentraremos más en algunos scripts para listar de cada clase, los atributos, métodos, propiedades y ejemplos.
Como siempre si tienen alguna o consulta, la pueden postear acá, o me pueden enviar un mail a JCimadom@Prisma.cc.
Anexo
Listados de Providers
Listado de clases
|
Sección |
Descripción |
|
Win32 Classes |
Esquema de clases incluidas dentro del namespace root\cimv2. Estas son las clases primarias para la operatoria con los sistemas operativos de Windows |
|
WMI Registry Classes |
Clases para manipular el registro |
|
WMI System Classes |
Clases predefinidas que están incluidas en todos los namespaces del core de WMI. Está pueden ser reconocidas facilmente ya que usan un doble guión bajo (__) al comienzo de cada nombre. Estas clases proveen mucho del funcionamiento básico para WMI. |
|
Monitor Display Classes |
Estas clases contienen información suministrada por el WDM Provider, y nos dan información acerca del monitor y la placa de video. Estas están definidas en root\WMI. |
|
MSFT Classes |
Clases de Microsoft que usualmente sirven para manipular componentes del Sistema Operativo como ser eventos remotos y "policy extensions" |
|
CIM Classes |
Esquema de clases del modelo CIM. Gracias a este modelo, podemos escribir nuestras propias clases. |
|
MSMCA Classes |
Clases que usualmente sirven para manipular y describir un evenyo del sistema, estas vienen incluidas en el sistema Operativo. |
Algunos scripts de ayuda
Listar los Namespaces existentes en el equipo
'---------------------------------------------------------------------------------------------------------------
Set loc = CreateObject("WbemScripting.SWbemLocator")
wscript.echo "root"
GetNamespaces "root", 1
Sub GetNamespaces(Path, Level)
Set WbemServices = loc.ConnectServer( , path )
Set Namespaces = WbemServices.ExecQuery("Select * From __Namespace")
For Each Namespace in Namespaces
Wscript.Echo Space(5*level) & Namespace.Name
GetNamespaces path & "\" & Namespace.Name, Level+1
Next
End Sub
'---------------------------------------------------------------------------------------------------------------
Listar los Providers existentes en el equipo
'---------------------------------------------------------------------------------------------------------------
Set shell = CreateObject("WScript.Shell")
Set loc = CreateObject("WbemScripting.SWbemLocator")
GetNamespaces "root", 1
Sub GetNamespaces(Path, Level)
Set WbemServices = loc.ConnectServer( , path )
Set Namespaces = WbemServices.ExecQuery("Select * From __Namespace")
For Each Namespace in Namespaces
Set Providers = WbemServices.ExecQuery("Select * From __Provider")
For Each Provider in Providers
key = "HKEY_CLASSES_ROOT\CLSID\" & Provider.CLSID
DLL=""
if Provider.CLSID <>"" Then
On Error Resume Next
DLL=shell.RegRead( key & "\InProcServer32\" )
If DLL="" Then DLL=shell.RegRead( key & "\LocalServer32\" )
On Error Goto 0
End If
WScript.Echo Provider.Name & ", " & DLL
Next
GetNamespaces path & "\" & Namespace.Name, Level+1
Next
End Sub
'---------------------------------------------------------------------------------------------------------------
Listar las clases dentro de cada namespace
'---------------------------------------------------------------------------------------------------------------
Set loc = CreateObject("WbemScripting.SWbemLocator")
GetNamespaces "root", 0, "root"
Sub GetNamespaces(Path, Level, NamespaceName)
Set WbemServices = loc.ConnectServer( , path )
Set classes=WbemServices.SubClassesOf
WScript.Echo Space(5*Level) & NamespaceName & ": " & classes.count
Set Namespaces = WbemServices.ExecQuery("Select * From __Namespace")
For Each Namespace in Namespaces
GetNamespaces Path & "\" & Namespace.Name, Level+1, Namespace.Name
Next
End Sub