¿Sabías que puedes monitorear casi todas las acciones en Windows? No, no necesitas comprar algún software elegante. La infraestructura monitorea eventos como cuando los servicios inician y se detienen, cuando alguien crea un archivo o carpeta, y más, ya está ahí a través de los eventos de Windows Management Instrumentation (WMI).
Los eventos de WMI no son una característica específica de PowerShell, pero una de las formas más fáciles de aprovechar los eventos de WMI y crear algunas herramientas útiles es mediante PowerShell. En este tutorial paso a paso, aprenderás cómo aprovechar los eventos de WMI con PowerShell y adquirirás las habilidades para construir algunas herramientas de monitoreo prácticas.
¡Vamos allá!
Prerrequisitos
Verás muchas demostraciones en este tutorial práctico. Si deseas seguir alguna de las demos, asegúrate de tener lo siguiente:
- Windows 7+ o Windows Server 2012+ – Este tutorial usará Windows Server 2019.
- Sesión iniciada como usuario en el grupo de administradores locales.
- Windows PowerShell 5.1 o PowerShell 6+ – Este tutorial usará PowerShell v7.1.2.
Comprensión de WMI y CIM
Antes de sumergirte en los eventos de WMI, es importante entender primero la infraestructura sobre la cual están construidos. Aunque este tutorial no se adentrará en los detalles de WMI, siempre puedes consultar la documentación de WMI de Microsoft para obtener más información.
WMI y su modelo de datos relacionado, el Common Information Model (CIM), son modelos incorporados en Windows que almacenan prácticamente cualquier información relacionada con el funcionamiento interno de Windows y lo que se está ejecutando en él.
WMI y CIM son herramientas poderosas que los administradores utilizan para gestionar Windows tanto local como remotamente. Mediante el uso de WMI o CIM, los administradores pueden consultar información en un sistema Windows, como aplicaciones instaladas, estado de servicios, archivos en el sistema de archivos y prácticamente todo lo demás.
WMI y CIM son la forma en que muchas soluciones de monitoreo empresarial recopilan información sobre la salud del sistema operativo y las aplicaciones. Pero no es necesario comprar una herramienta costosa de monitoreo para aprovechar WMI; ¡tienes PowerShell!
Comencemos con los dos elementos básicos, y a medida que avancemos, aprenderás los demás elementos necesarios:
- Clases: Las clases son los eventos y propiedades a los que la aplicación, como PowerShell, puede llamar para leer y actualizar datos. Las clases se encuentran dentro de un espacio de nombres.
- Espacio de nombres: El espacio de nombres es un contenedor para clases relacionadas con WMI. Piensa en él como una carpeta “Mis imágenes” que contiene contenido relacionado con imágenes. Hay varios espacios de nombres, y el más común es CIMv2, que contiene la mayoría de las clases del sistema operativo. Pero, todos los espacios de nombres se encuentran bajo el gran espacio de nombres único Root.

WMI vs. CIM
WMI y CIM son ambos métodos para interactuar con el repositorio en un sistema Windows que contiene toneladas de información y para trabajar con eventos de WMI (más sobre eso más adelante). Pero, ambos métodos tienen algunas diferencias, principalmente la forma en que los administradores interactúan con ellos de forma remota.
WMI comenzó con Windows NT4 y fue la forma original (y única) de interactuar con el repositorio. Cuando se administra un sistema Windows con WMI, Windows utiliza Modelo de Objetos de Componentes Distribuidos (DCOM). DCOM es un protocolo remoto que WMI utiliza para exponer información dentro del repositorio de datos en una máquina Windows.
Para trabajar a través de una red, DCOM utiliza Llamada de Procedimiento Remoto (RPC). Para comunicarse a través de una red, RPC utiliza rangos de puertos dinámicos, lo que a veces es un desafío para los firewalls y dispositivos de Traducción de Direcciones de Red (NAT).
Si tienes problemas con RPC, consulta el artículo Probar Conexiones RPC con los Puertos Dinámicos.
Microsoft decidió aprovechar CIM para proporcionar un enfoque más moderno para interactuar con el repositorio de datos en Windows. En lugar de RPC, CIM utiliza WS-MAN (Web-Service for Management), un protocolo HTTP mucho más adecuado para la gestión remota.
A lo largo de este artículo y otros, WMI y CIM pueden utilizarse indistintamente. El repositorio de datos con el que interactúan ambos métodos de gestión se llama típicamente repositorio WMI. Casi todos los términos se refieren a WMI, mientras que CIM se menciona típicamente en los cmdlets de PowerShell.
WMI vs. CIM y PowerShell
Afortunadamente, tienes algunas opciones cuando se trata de WMI y CIM con PowerShell. PowerShell admite ambas formas de interactuar con el repositorio de datos. Cuando ejecutas el comando Get-Command
en PowerShell, puedes notar varios cmdlets de Wmi
como Get-WmiObject
, Invoke-WmiMethod
, Remove-WmiObject
, Register-WmiEvent
, y Set-WmiInstance
.
Si estás ejecutando Windows PowerShell 3 o superior (¡lo cual deberías estar!), también verás algunos cmdlets con nombres similares como Get-CimInstance
, Get-CimClass
, y Remove-CimInstance
.
¿Qué cmdlets de PowerShell deberías usar? La respuesta es simple; los cmdlets de CIM. CIM es el nuevo estándar en el que Microsoft se está enfocando. ¡Ni siquiera están disponibles los cmdlets de WMI en PowerShell Core!
Consultar WMI: Lo básico
Antes de poder trabajar con eventos de WMI, debes entender cómo consultar WMI con PowerShell. Consultar información del repositorio WMI es el uso más común de los datos de WMI.
Para consultar datos de WMI en el mundo de PowerShell, el Get-CimInstance
es tu aliado. Este cmdlet tiene varias formas de consultar datos de WMI, pero este tutorial se centrará en el parámetro Query
. El parámetro Query
te permite proporcionar una consulta Windows Query Language (WQL) para consultar WMI.
Por ejemplo, tal vez quieras encontrar todas las instancias de WMI en la clase Win32_Service
. Similar a SQL, usarías la consulta Select * from Win32_Service
, como se muestra a continuación. El asterisco (*
) le indica a WMI que devuelva todas las propiedades de cada instancia encontrada.

En el ejemplo anterior, encontraste todas las instancias de cada servicio en la clase Win32_Service
, pero ¿qué pasa si solo quieres encontrar algunas? En ese caso, usarías la WHERE
cláusula. La cláusula WHERE
crea un filtro para devolver solo las instancias que coinciden con una condición específica.
La cláusula WHERE
le dice a Get-CimInstance
que solo devuelva instancias donde la propiedad de la instancia coincida con un valor específico. Por ejemplo, tal vez solo quieras encontrar las instancias de servicio donde la propiedad State
sea Running
. Si es así, definirías la cláusula WHERE
como Where State='Running'
, como se muestra a continuación.
Puedes ver abajo que Get-CimInstance
solo devolvió las instancias de servicio donde la propiedad State
era igual a Running
.

Eventos de WMI: Las acciones de WMI
WMI contiene un gran repositorio de información sobre miles de elementos en Windows. Puedes acceder a esa información consultándola como lo hiciste anteriormente, pero también tiene otra característica menos conocida; eventos de WMI.
En Windows, en cualquier momento, podrían estar ocurriendo cientos de eventos. Cuando usas diversas funciones de Windows como crear archivos, detener y iniciar servicios, instalar software o cualquier otra cosa, probablemente se desencadene un evento de WMI.
Prácticamente todas las acciones que se realizan en Windows pueden ser expuestas mediante un evento de WMI. Cuando se realiza una acción en Windows, Windows desencadena un evento a través de su infraestructura interna. Por defecto, no puedes ver estos eventos; están sucediendo en segundo plano. Para ver estos eventos, debes subscribirte a ellos.
Construyendo un Script de Monitoreo de Servicios con PowerShell
Para demostrar cómo funcionan los eventos de WMI, en lugar de aburrirte con toneladas de información, vamos a construir una herramienta útil. Dado que los eventos de WMI ocurren cuando sucede un evento en Windows, puedes crear algunas herramientas de monitoreo prácticas usándolos.
Quizás te gustaría escribir un mensaje en un archivo de registro cuando cambia el estado de un servicio de Windows en un servidor crítico. Luego, puedes suscribirte a los eventos de WMI que se activan cuando ocurren esas acciones. Cuando te suscribes al evento y se activa, puedes realizar alguna acción como registrar en un archivo, enviar un correo electrónico o cualquier otra cosa que puedas hacer con PowerShell.
En lugar de comprar una solución de monitoreo costosa, ¡un simple script de PowerShell puede ser una excelente herramienta de monitoreo para el hombre pobre! Si estás listo, abre tu consola de PowerShell y ¡empecemos!
Encontrar la Clase CIM
Dentro de WMI, al igual que con las instancias estáticas, los eventos están contenidos en clases. Estas clases contienen todos los datos estáticos que consultaste anteriormente y donde se desencadenan cambios en esas instancias. Puedes encontrar una lista de todas las clases CIM en la documentación de Microsoft.
Para encontrar todas las clases CIM, ejecuta el Get-CimClass
cmdlet sin parámetros. El cmdlet Get-CimClass
, por defecto, devuelve todas las clases en el espacio de nombres ROOT/cimv2
. El espacio de nombres ROOT/cimv2
es el “principal” espacio de nombres donde se almacenan casi todas las clases interesantes de Windows.
Sin embargo, como puedes ver a continuación, se devuelven muchas clases.

Quizás has investigado un poco y finalmente te has dado cuenta de que los servicios de Windows se almacenan en la Win32_Service
. Entonces, cuando conozcas el nombre de la clase, utiliza el parámetro ClassName
para especificar el nombre, como se muestra a continuación.

Encontrando las Propiedades de la Clase CIM
Una vez que sepas a qué clase buscar, debes averiguar qué propiedad examinar. Cuando cambia el valor de una propiedad de instancia (o se crea o elimina toda una instancia), se dispara un evento. Debes capturar ese cambio de estado. Para hacerlo, debes saber qué propiedad te gustaría monitorear.
Para encontrar esa propiedad, inspecciona la propiedad CimClassProperties
del objeto PowerShell en la instancia de clase CIM que consultaste en la sección anterior.
Observa a continuación que una de esas propiedades es la propiedad State
.

Ahora que sabes qué clase CIM y qué propiedad te gustaría monitorear, ¡es hora de suscribirte al evento WMI!
Creando una Suscripción a Eventos WMI: Descripción General de Alto Nivel
Crear una suscripción a eventos WMI puede ser una tarea confusa si nunca has creado una antes. Para ayudarte a mantener claras las acciones, primero cubramos el panorama antes de entrar en detalles y esbocemos los pasos básicos.
Crear una suscripción a eventos WMI requiere cuatro pasos generales:
- Creando la consulta WQL – Al igual que al consultar datos estáticos, debes crear una consulta WQL que coincida con el tipo de evento de WMI que te gustaría ver. Pero, a diferencia de la consulta en el almacén de datos, debes emplear algunos componentes más complicados en la consulta, como las clases del sistema y verificar ciclos (más sobre esos luego).
- Creando el filtro de eventos – Una vez que hayas creado la consulta WQL, debes crear el filtro de eventos. El filtro de eventos registra la consulta WQL en CIM.
- Creando el consumidor – El consumidor define la acción a tomar cuando la consulta del filtro de eventos devuelve un cambio en la clase. Por ejemplo, cada vez que se inicia, detiene, crea o elimina un estado de servicio, el consumidor activa una acción.
- Vinculando el filtro de eventos al consumidor – El pegamento que enlaza la consulta de WMI de Windows con el consumidor. El enlace es lo que notifica al consumidor cuando el filtro de eventos ha recibido una coincidencia.
Cuando juntas cada uno de estos elementos, creas una subscripción.

Creando la Consulta WQL
A WQL query for a WMI event looks a bit different than performing a simple query with Get-CimInstance
. Below you’ll find a typical WMI event query.
Dado que la consulta WQL puede parecer intimidante al principio, vamos a descomponerla y entender cómo funciona cada componente.
La Clase del Sistema
En el ejemplo de Get-CimInstance
, descubriste que te gustaría ser notificado cuando se realice un cambio en una instancia en la clase Win32_Service
. Todavía necesitas esta clase, pero en lugar de una consulta WQL que se vea así:
En cambio, la consulta comenzará de la siguiente manera. La clase principal que estás consultando no es la clase que contiene la instancia sobre la cual deseas recibir notificaciones. En cambio, la clase es una clase del sistema.
Las clases del sistema son clases internas que representan el tipo de cambio que ocurre en el evento. Un evento de WMI tiene cuatro tipos de clases del sistema:
- InstanceModificationEvent – Verifica cualquier cambio en los valores de las propiedades de una instancia en una clase. Esta es la clase que utilizarás porque deseas monitorear el valor de la propiedad
Status
en una instancia (servicio) de la claseWin32_Service
. - InstanceCreationEvent – Verifica la creación de nuevas instancias. Si, por ejemplo, deseas monitorear la creación de nuevos servicios, utilizarías esta clase del sistema.
- InstanceDeletionEvent – Verifica la eliminación de instancias. Si, por ejemplo, deseas monitorear la eliminación de servicios, utilizarías esta clase del sistema.
- InstanceOperationEvent – Esta clase del sistema verifica todos los tipos de eventos, modificación, creación y eliminación.
Para nuestro script de monitoreo, el comienzo de la consulta WQL se verá de la siguiente manera:
Los nombres de las clases del sistema WMI siempre comienzan con dos guiones bajos (\_\_) seguidos del nombre de la clase.
El ciclo de comprobación
A continuación, tienes el ciclo de comprobación. El ciclo de comprobación incluye la palabra clave within
y un valor que representa un intervalo de sondeo expresado en segundos.
Los eventos de WMI no son en tiempo real, por lo que debes definir un intervalo específico para tu suscripción para comprobar cambios. Si, por ejemplo, configuras el ciclo de comprobación en 10, la suscripción comprobará un cambio desde el último ciclo de sondeo cada 10 segundos. Si se encuentra un cambio, activa el consumidor.
¡Si una instancia cambia, se crea o se elimina dependiendo de la clase del sistema dentro del intervalo de sondeo, el cambio no se detectará! ¡Considera la frecuencia que necesitas pero asegúrate de que sea amigable con la CPU y la memoria!
Para el ejemplo de monitoreo de servicios del tutorial, configuremos el ciclo de comprobación en 10 para sondear WMI cada 10 segundos en busca de un cambio en un servicio de Windows. ¡La consulta de WQL está creciendo!
El Filtro
Finalmente, para completar la consulta de WQL, debes definir un filtro para limitar las instancias devueltas de la clase del sistema. Debes definir ese filtro en la forma siguiente. En este caso, la clase CIM que te gustaría monitorear se llama la TargetInstance
.
ISA
es un operador que aplica una consulta a las subclases de una clase especificada.
Dado que el tutorial está construyendo una suscripción para monitorear servicios de Windows, crearías el filtro de la siguiente manera:
Como está, el filtro busca Win32_Service
en todas las instancias. Si solo desea monitorear una única propiedad, tal vez un servicio específico, debe usar el operador AND
.
Los operadores AND o OR añaden otras condiciones para obtener resultados más precisos.
El filtro tutorial (y toda la consulta) ahora está completo como el fragmento de código a continuación.
Creando el Filtro de Eventos
Ahora que tiene el filtro de consulta, ¡el resto del proceso es mucho más fácil de entender! Ahora debe crear el filtro de eventos para usar esa consulta. Un filtro de eventos es en realidad otra instancia CIM que forma parte de la clase __EventFilter
dentro del espacio de nombres Root/subscription
.
A continuación puedes ver un fragmento de código con todo lo necesario. El script siguiente asigna la consulta WQL a la variable $FilterQuery
. Luego crea un hashtable que contiene cada una de las propiedades requeridas y los valores necesarios para el filtro de eventos. Después, ejecuta el New-CimInstance
cmdlet para crear finalmente el filtro de eventos.
El objeto de instancia CIM resultante se almacena en una variable ($CIMFilterInstance
) para su uso posterior.
Ahora, ejecuta Get-CimInstance
para verificar que se haya creado la nueva instancia CIM de __EventFilter
.

Creación del Consumidor
A continuación, es hora de crear el consumidor o la acción que ocurrirá cuando Windows active el evento WMI. Al crear el consumidor, tienes algunas opciones dependiendo del tipo de acción que te gustaría activar.
- ActiveScriptEventConsumer – Ejecuta un script en un lenguaje de secuencias de comandos arbitrario como VBscript.
- CommandLineEventConsumer – Inicia un proceso
Asegúrese de que el ACL del ejecutable esté definido correctamente para evitar que alguien reemplace el EXE con un binario malicioso.
- LogFileEventConsumer – Crea un registro de texto.
- NTEventLogEventConsumer – Escribe un evento en el registro de eventos de Windows.
- SMTPEventConsumer – Envía un correo electrónico.
Para este tutorial, usemos el tipo de consumidor LogFileEventConsumer
para escribir en un archivo de registro cuando el servicio coincida en la consulta WQL cambie.
Cada clase de consumidor tiene sus propios parámetros, así que verifica las
CimClassProperties
para más detalles sobre cada clase, por ejemplo,(Get-CimClass -ClassName __NTEventLogEventConsumer).CimClassProperties
.
Una vez que hayas creado el consumidor, nuevamente, verifica su existencia con Get-Ciminstance
.

Vinculando el Filtro de Evento y el Consumidor
¡Finalmente, es hora de completar esta suscripción y vincular el filtro de evento y el consumidor juntos! Como podrías haber imaginado, crear la vinculación significa crear una instancia CIM más. Esta vez debes crear una nueva instancia en la clase __FilterToConsumerBinding
.
El fragmento de código a continuación está utilizando las dos instancias creadas anteriormente (el filtro y el consumidor) como una tabla hash que define las propiedades necesarias para crear una nueva instancia. Luego se pasa a New-CimInstance
como antes para crear la vinculación.
Como siempre, confirma que la vinculación se haya creado ejecutando Get-CimInstance
nuevamente.
Como puedes ver, la vinculación tiene información sobre tanto el Filtro
como el Consumidor
.

Probando la Suscripción
¡Finalmente has terminado! ¡Es hora de probar los frutos de tu trabajo! Lo único que necesitas hacer ahora es cambiar el estado del servicio BITS para ver si PowerShell escribe una entrada en el archivo de registro en C:\MyCIMMonitoring.txt.
Dependiendo del estado del servicio BITS, detenlo o arráncalo o simplemente reinícialo con el cmdlet Restart-Service
.
Espera unos 10 segundos y verifica el C:\MyCIMMonitoring.txt. Ahora deberías ver el Texto
en el archivo de registro que definiste al crear el consumidor.

Para monitorear toda la actividad de eventos de WMI, revisa el registro de eventos de Windows en la ruta Aplicaciones y Servicios\Log\Microsoft\Windows\WMI-Activity\Operational.
Detener y Limpiar la Suscripción
Una vez que hayas terminado con la suscripción, es hora de limpiarla. Para detener y eliminar la suscripción de eventos de WMI, debes eliminar las instancias de filtro de eventos, consumidor y enlace.
Elimina el filtro de eventos encontrando primero la instancia con Get-CimInstance
.

A continuación, elimina el consumidor de la misma manera.

Finalmente, elimina el enlace. La propiedad para encontrar el enlace es un poco diferente. En lugar de la propiedad Nombre
, la instancia de enlace tiene una propiedad Filtro
que en realidad es un objeto con una propiedad Nombre
.

Conclusión
WMI/CIM es un sistema práctico y potente para encontrar información sobre Windows y monitorearlo con eventos de WMI. Monitorear cambios con eventos de WMI te brinda una gran visibilidad y una reacción más rápida ante posibles problemas, facilitando la automatización de una respuesta para cada evento.
Para obtener un gran ejemplo del mundo real, consulta Cómo realizar un seguimiento de los cambios en Active Directory con eventos de WMI.
Source:
https://adamtheautomator.com/your-goto-guide-for-working-with-windows-wmi-events-and-powershell/