¿Alguna vez ha necesitado que una tarea se lance tan pronto como un archivo se ha lanzado en un directorio? Si es así, ¿cuál fue su solución? ¿Preparó una tarea programada para ejecutarse cada minuto para comprobar constantemente la carpeta en busca de nuevos archivos? Esa fue mi solución durante mucho tiempo. No funcionaba muy bien porque necesitaba que viera un nuevo archivo casi en tiempo real. No quería esperar tanto como 60 segundos para que se iniciara la siguiente tarea programada. Utilicé las tareas programadas hasta que descubrí una forma mejor: suscripciones permanentes a eventos de WMI.
¿Qué es una suscripción a un evento de WMI?
La suscripción a un evento de WMI es un método para suscribirse a ciertos eventos de WMI. Los eventos de WMI se disparan constantemente dentro del repositorio de WMI, basados en una serie de actividades diversas. WMI tiene varias clases dentro del repositorio. Algunas de estas clases se llaman clases de eventos. Las clases de eventos no necesariamente contienen datos estáticos como muchas otras clases. En su lugar, simplemente informan sobre un tipo específico de actividad. Por ejemplo, en nuestro escenario, quiero saber cuando un archivo se coloca en una carpeta. Para ello, me suscribiría a la clase de eventos __InstanceCreationEvent y usaría una instancia de destino de la clase CIM_DataFile. Esto me permitiría ver todos los archivos que se mueven por el ordenador.
Hay dos tipos de suscripciones a eventos de WMI: temporales y permanentes. Si se crean con PowerShell, las suscripciones a eventos temporales se eliminan tan pronto como se cierra la consola de PowerShell. Son buenos para las pruebas, pero no funcionan bien para los scripts de producción real. Es por eso que necesitará crear suscripciones permanentes. Estas suscripciones se almacenan en el repositorio de WMI y no dependen de PowerShell en absoluto. Siguen funcionando cuando se cierra la consola de PowerShell o se reinicia el PC. Por esta razón, en este artículo nos concentraremos en las suscripciones a eventos permanentes.
Una suscripción a un evento de WMI consiste en tres partes: el filtro, el consumidor, y la vinculación. Veamos estas partes en detalle.
El filtro
El filtro WMI es una consulta WQL representada por la clase __EventFilter WMI. Esta parte de la suscripción se utiliza para reducir lo que se devuelve por la clase de eventos. Ya he mencionado la clase CIM_DataFile. Si me suscribiera a esta clase, obtendría todas las instancias de todos los archivos que se mueven por el ordenador. Sólo quiero monitorear una sola carpeta, así que aplicaría un filtro que sólo busca los archivos que se agregan a esa carpeta. El filtro también es donde se especifica la frecuencia de las encuestas. A diferencia de las tareas programadas, el sondeo se puede especificar hasta el segundo!
El consumidor
La siguiente pieza de una suscripción es el consumidor. El consumidor instruye a la suscripción sobre qué hacer cuando se detecta un evento. En nuestro ejemplo, el consumidor se llama el objeto ActiveScriptEventConsumer. Este es el objeto que se crea, que especifica el script que se ejecutará cuando el evento que buscamos se dispare.
La encuadernación
Por último, necesitamos la encuadernación. Este es otro objeto que esencialmente une al consumidor y al filtro. Está representado por la clase WMI __FiltroParaConsumidorVinculaciónClase WMI. La vinculación es una pieza necesaria en la suscripción general. Esencialmente permite al consumidor ejecutar nuestro guión.
He creado un módulo de PowerShell llamado FileMonitor que permite crear fácilmente un consumidor de eventos WMI permanente que monitoriza la creación de archivos. FileMonitor tiene tres funciones: New-FileMonitor, Remove-FileMonitor, y Get-FileMonitor. Usando estas funciones, usted puede crear y manipular sus varias suscripciones de WMI sin tener que preocuparse por todo el código oscuro requerido para manejarlas.
Por ejemplo, digamos que quiero monitorear la carpeta C:MyFolder cada 10 segundos para cualquier archivo. Si un archivo aparece, quiero que se registre en el archivo de registro C:MyLogFile.log. Para ello, crearé un script de PowerShell que agregará esta información en C:MyLogFile.log cuando un archivo se deje caer en la carpeta C:MyFolder.
El módulo FileMonitor sólo crea y gestiona el consumidor de eventos permanentes. Por lo tanto, depende de ti crear un par de scripts con las acciones que quieres que se realicen después de que un archivo entre en la carpeta MyFolder. Primero, querrás crear un script VBScript en la raíz del directorio C: llamado callps1.vbs. Desafortunadamente, no es posible llamar a un script de PowerShell directamente desde un consumidor de eventos, así que estamos obligados a usar un script VBScript de la vieja escuela como una retransmisión a un script de PowerShell.
Tengo esto en mi guión de C:callps1.vbs.
Set objShell = CreateObject(«Wscript.shell»)
objShell.run(«powershell.exe -WindowStyle Hidden -executionpolicy bypass -file «»C:callfromvbs.ps1″»)
Simplemente estoy usando este script VBScript para lanzar el script de PowerShell C:callfromvbs.ps1. A continuación, crear el script callfromvbs.ps1 y añadir una sola línea.
Add-Content -Path $0027C:MyLogFile.log$0027 -Valor $0027Un archivo se encontró en la carpeta C:MyFolder$0027.
Este simple y muerto script simplemente añade una línea en el archivo C:MyLogFile.log con el texto «Se encontró un archivo en la carpeta C:MyFolder».
Ahora que tenemos el guión de retransmisión de VBScript y el guión de PowerShell que nos gustaría ejecutar, es sólo cuestión de crear el consumidor de eventos permanentes de WMI con el cmdlet New-FileMonitor!
New-FileMonitor -Name $0027MyMonitor$0027 -MonitorInterval 10 -FolderPath $0027C:MyFolder$0027 -ScriptFilePath C:callps1.vbs
Ejecute esto, y si quiere asegurarse de que fue creado, ejecute Get-FileMonitor poco después. Ahora debería ver el monitor de archivos que acaba de crear. Esto significa que has creado con éxito tu primer evento permanente de WMI consumidor para monitorear archivos! Pruébelo colocando cualquier archivo en la carpeta C:MyFolder. Fíjate en cómo se crea el archivo C:MyLogFile.log y contiene una sola línea.
Los consumidores de eventos permanentes de WMI pueden hacer mucho más que vigilar los archivos. Te reto a que te familiarices con los consumidores de eventos de WMI y veas qué más se te ocurre.