Home > Windows, scripting > Listar propiedades de un proceso o servicio de sistema operativo

Listar propiedades de un proceso o servicio de sistema operativo

Hola,

Hoy veremos un script muy sencillo escrito en VBS que consulta por WMI a un proceso. La lógica del script es muy sencilla y se puede adaptar a vuestras necesidades con pocas modificaciones.

 '################
' BindToProcessWmi.vbs
'
' Author: Roberto Clemente Bustamante - Digilux Admin Team
'################

'Declaración de variables y constantes
dim objfile
dim objdestination
dim strline

CONST WTER ="processCPUperc.txt"       'NOMBRE FICHERO PARA ESCRIBIR
'Inicializacion objeto FSO y fichero de log
set objfile = createobject("scripting.filesystemobject")
set objdestination = objfile.opentextfile(WTER,8,true)

'Recuperar procesos que estén en uso en la CPU

for each Process in GetObject("winmgmts:{impersonationLevel=impersonate}//localhost").ExecQuery("Select name,PercentProcessorTime,IDProcess from Win32_PerfFormattedData_PerfProc_Process where PercentProcessorTime > 0")' where IDProcess=" & strproc)

'Descarte del total y del no utilizado
if (process.name = "_Total" or process.name = "Idle") then
'Aqui se puede introducir código para cuando se cumpla la condicion
else
'Volcado al log
objdestination.writeline day(now)& "-" & month (now)& "-" & year(now)& ":" & Hour(now) & ":"& Minute(now) & " - " & process.name & " - %: " & process.percentprocessortime & " - ID:" & process.idprocess

end if

Pues bien, Tal y como hemos hecho con otros scripts, este script es mas una herramienta adaptable que un script funcional, un fragmento de código que podeis reutilizar una y otra vez en multitud de escenarios.

Para empezar, os recomiendo la lectura del post wmi-windows-management-intrumentation-a-vista-de-pajaro/

En este ejemplo vemos como hacer una consulta con WQL a WMI para recuperar un dato. Concretamente la clase a la que vamos a consultar está definida en la msdn aqui

Si nos fijamos en la definición de la clase:

class Win32_PerfFormattedData_PerfProc_Process : Win32_PerfFormattedData { string Caption; uint32 CreatingProcessID; string Description; uint64 ElapsedTime; uint64 Frequency_Object; uint64 Frequency_PerfTime; uint64 Frequency_Sys100NS; uint32 HandleCount; uint32 IDProcess; uint64 IODataBytesPerSec; uint64 IODataOperationsPerSec; uint64 IOOtherBytesPerSec; uint64 IOOtherOperationsPerSec; uint64 IOReadBytesPerSec; uint64 IOReadOperationsPerSec; uint64 IOWriteBytesPerSec; uint64 IOWriteOperationsPerSec; string Name; uint32 PageFaultsPerSec; uint64 PageFileBytes; uint64 PageFileBytesPeak; uint64 PercentPrivilegedTime; uint64 PercentProcessorTime; uint64 PercentUserTime; uint32 PoolNonpagedBytes; uint32 PoolPagedBytes; uint32 PriorityBase; uint64 PrivateBytes; uint32 ThreadCount; uint64 Timestamp_Object; uint64 Timestamp_PerfTime; uint64 Timestamp_Sys100NS; uint64 VirtualBytes; uint64 VirtualBytesPeak; uint64 WorkingSet; uint64 WorkingSetPeak; };

podemos observar que nuestra query WQL tratará de recuperar lo siguiente:

Name – Nombre del ejecutable involucrado
PercentProcessorTime – Porcentaje de uso de procesador
IDProcess – Identificador de proceso (PID)

Aunque en realidad podriamos recuperar cualquier propiedad definida en esa clase. Además recuperamos los resultados siempre y cuando el porcentaje de uso del procesador utilizado por el proceso sea mayor que 0 (PercentProcessorTime > 0)

La condición comentada (where IDProcess=” & strproc)) nos permitiria seleccionar tan solo aquel proceso que tenga el PID igual que la variable strproc.

En cuanto a la sentencia:
for each Process [...]

es un bucle for each … next (Ref: http://msdn.microsoft.com/en-us/library/5ebk1751(VS.80).aspx y se utiliza para realizar iteraciones por cada elemento encontrado en una colección. (procesa el primero, luego el siguiente y así hasta el final de los resultados)

Hay que entender, que cuando hacemos la consulta WQL esta puede arrojar varios resultados, entonces el bloque de acciones lo ejecutará por cada resultado encontrado, iterando entre los mismos.

El bloque de acciones así como la consulta WQL es modificable a vuestro gusto. La lógica de composición de código es sencilla:

1.- Identificar la clase a la que necesitamos consultar aqui

2.- Una vez identificada la clase, escoger las propiedades que nos interesan, para construir la consulta WQL. Para ello identificaremos los siguientes elementos:

-Propiedades (Datos que queremos que arroje la query) En el ejemplo, son: name,PercentProcessorTime,IDProcess,caption
-Condiciones (Nos ayudan a tratar menos resultados, o escoger el resultado que realmente nos interesan. En nuestro ejemplo:
where PercentProcessorTime > 0

Si nos fijamos, escojemos una condicion (mayor que 0) y se compara con una propiedad (desde un punto abstracto, una columna) Dejarán de aparecer todos aquellos valores que no cumplan la condición. Otra posibilidad:
where IDProcess = 10301 (Donde la propiedad IDProcess (PID) sea igual a 10301)

- Clase (Aquella que contiene las propiedades que nos interesan, en nuestro caso Win32_PerfFormattedData_PerfProc_Process como explicamos antes)

La consulta, muy similar por no decir igual al lenguaje SQL

select [propiedades] from [clase] where [condicion]

Por ejemplo, imaginaros que nos gustaria conocer los pid’s de ejecución de un proceso mediante un script, solo de aquellos servicios en estado arrancado. De los servicios nos interesan, el path al ejecutable involucrado, su nombre largo, su nombre corto, su modo de arranque y estado actual.

Revisando las clases disponibles escogemos Win32_Service. Identificamos las propiedades:
-Caption (nombre largo)
-Name (nombre corto)
-Pathname (ruta hasta el ejecutable)
-startmode (modo de arranque del servicio)
-State (Estado del servicio)

Como solo queremos que nos muestre los que están running, seleccionaremos la condición: where state=”Running”

Pues bien, construimos la sentencia:

Select caption,name,pathname,processid ,startmode, state from Win32_Service where state = “Running”

Ahora cogemos el script de arriba, y lo modificamos para que se ajuste a nuestras nuevas necesidades. Antes de pegar el código, veamos como utilizar un where con una condicional de texto. Al estar dentro de código VBS la select WQL y esta tener que utilizar comillas, estas deben de ser escapadas, para que no corte la sentencia:

for each service in GetObject("winmgmts:{impersonationLevel=impersonate}//localhost").ExecQuery("Select caption,name,pathname,processid ,startmode, state from Win32_Service where state = ""Running""")

Fijaos en la construcción del final: ""Running""") ?

- Las primeras dos, escapan la doble comilla para que en realidad pase una sola.

- Las 3 del final es exactamente lo mismo, solo que se añade una mas puesto que aquí sí que termina la sentencia, y por lo tanto hay que cerrar el parentesis.

El script una vez modificado, deberia quedar así:

dim objfile dim objdestination dim strline CONST WTER ="Services.txt" 'NOMBRE FICHERO PARA ESCRIBIR set objfile = createobject("scripting.filesystemobject") set objdestination = objfile.opentextfile(WTER,8,true) for each service in GetObject("winmgmts:{impersonationLevel=impersonate}//localhost").ExecQuery("Select caption,name,pathname,processid ,startmode, state from Win32_Service where state = ""Running""") objdestination.writeline day(now)& "-" & month (now)& "-" & year(now)& ":" & Hour(now) & ":"& Minute(now) & " - " & service.caption & " - " & service.name & " - PathName: " & service.pathname & " - ID:" & service.processid & " - " & service.startmode & " - " & service.state next

Siguiendo estas instrucciones, podreis consultar cualquier cosa a WMI.

Espero que este post y/o este código os sea de ayuda. Nos gustaria mucho recibir feedback por vuestra parte sobre los diferentes usos que hayais hecho del mismo, modificaciones, etc así que desde digilux.es os animamos a que participeis mediante los comentarios!

pixelstats trackingpixel
  1. August 6th, 2009 at 18:17 | #1

    hola Rubick, me pase para hojear tu blog y permiteme darte mis felicitacion ya que veo que lo tienes desde mediados del 2006. Y permiteme darte tambien mi opinion sobre el foro, revisando la pagina principal de tu blog veo que no tienes muchos comentarios por lo que la idea de poner un foro no la veo tan llamativa..aun :)

  2. August 7th, 2009 at 08:33 | #2

    Gracias por tus comentarios, somos varias personas las que escribimos aquí, cada uno especialista en un area de hecho este post no es mío ;)

    La idea de crear al foro, si bien es cierto que no hay comentarios, es crearlo orientado más bien a administradores ya que foros de ayuda hay muchos, pero en castellano y para administradores hay pocos o casi ninguno, de momento estoy viendo opciones ;)

  1. No trackbacks yet.