Cómo acceder a WMI (Windows Management Instrumentation) para consulta en equipos Windows 10 y Windows Server 2012, 2016 y 2019. Cómo ejecutar consultas para obtener datos del equipo como CPU, RAM, discos duros, aplicaciones instaladas, procesos, etc. Cómo hacer scripts PowerShell para obtener estos datos WMI y para realizar filtros, formato de salida, condicionales (if), etc.
- Establecer permisos para acceso a WMI en Windows en Windows 10 y Windows Server 2019.
- Ejecutar comandos WMI para obtener datos del equipo desde PowerShell.
- Obtener información del procesador CPU del equipo mediante WMI.
- Obtener información de la memoria RAM del equipo con WMI y PowerShell.
- Obtener información de la placa base (motherboard) del equipo con WMI y PowerShell.
- Obtener información de los discos duros instalados en el equipo con WMI y PowerShell.
- Obtener aplicaciones instaladas en el equipo con WMI y PowerShell.
Establecer permisos para acceso a WMI en Windows en Windows 10 y Windows Server 2019
Antes de ejecutar comandos WMI para obtener datos, nos debemos asegurar de que el usuario tiene permisos suficientes para acceder a la clave WMI que vayamos a usar. Para ello abriremos la consola de Control WMI, tanto en un equipo Windows 10 como Windows Server 2012, 2016, 2019, se abre de la misma manera, accediendo al menú Inicio y a Ejecutar (Windows + R):
Escribimos:
wmimgmt.msc
Y pulsamos en «Aceptar»:
En la consola Control WMI pulsaremos con el botón derecho sobre «Control WMI (local)». En el menú emergente pulsaremos en «Propiedades»:
Pulsaremos en la pestaña «Seguridad» [1]. Seleccionaremos la clave a la que queramos establecer los permisos, normalmente dentro de Root, la clave «CIMV2» [2]. Y pulsaremos en «Seguridad» [3]:
Seleccionaremos el usuario al que queramos dar permisos y marcaremos los permisos:
De esta forma este usuario podrá ejecutar comandos para obtener datos mediante WMI en el equipo, como indicamos a continuación.
Ejecutar comandos WMI para obtener datos del equipo desde PowerShell
Abriremos una ventana de comandos de Windows PowerShell:
Una pequeña comprobación para verificar que WMI funciona correctamente se puede hacer ejecutando el comando:
1 |
Get-WmiObject -query "SELECT * FROM Win32_OperatingSystem" |
Este comando nos debería devolver datos del sistema operativo actual, como la carpeta de sistema, la organización, el número de compilación, el usuario de registro, el número de serie y la versión:
Si ha funcionado correctamente, podremos usar la línea de comandos PowerShell para realizar consultas WMI de todo tipo. Con WMI y PowerShell se puede obtener infinidad de información, como mostramos a continuación.
Obtener información del procesador CPU del equipo mediante WMI
Para obtener información básica del procesador del equipo (CPU) mediante WMI podemos usar el comando:
1 |
Get-WmiObject win32_Processor |
Devolverá el fabricante y modelo de procesador, el ID, la velocidad y el tipo de socket:
Tmabién podremos obtener los datos anteriores ejecutando una query (consulta), con formato parecido al SQL:
1 |
Get-WmiObject -Query "Select * from Win32_Processor" |
Desde PowerShell casi siempre existen varias formas de obtener la misma o parecida información. Por ejemplo, si queremos obtener todos los datos de la CPU podremos usar este otro comando:
1 |
Get-CimInstance -Class CIM_Processor -ErrorAction Stop | Select-Object * |
Que devolverá todos los datos de la CPU de nuestro equipo: disponibilidad, estado, voltaje, ID, error, porcentaje de carga, tamaño de palabra, tamaño de memoria caché L2 y L3, velocidad de memoria caché L2 y L3, velocidad del procesador, tipo de procesador, revisión, socket, descripción, fabricante, fecha de instalación, velocidad de reloj, arquitectura, número de cores, número de procesadores lógicos, ID del procesador, si tiene habilitada la característica de virtualización, …:
Otra forma de mostrar todos los datos del procesador (CPU) con PowerShell y WMI, indicando que muestre todas las propiedades (campos de datos):
1 |
Get-WmiObject -Class Win32_Processor -ComputerName. | Select-Object -Property [a-z]* |
Como vemos, hay muchas formas de obtener los mismos datos en PowerShell. Usaremos la que más se ajuste al resultado que queramos obtener. Por ejemplo, el comando anterior, con una pequeña modificación, nos permitirá obtener sólo las propiedades (campos/columnas/datos) que queramos del procesador. Si queremos obtener únicamente el modelo (Name), podemos usar:
1 |
Get-WmiObject -Class Win32_Processor -ComputerName. | Select-Object -Property Name |
En el caso anterior, si únicamente queremos que el comando nos devuelva el dato, el modelo del procesador en este caso, sin el nombre de la columna, podemos usar el comando:
1 |
Get-WmiObject -Class Win32_Processor -ComputerName. | Select-Object -ExpandProperty Name |
Esto nos será muy útil en casos en los que queramos realizar operaciones en función de los valores obtenidos. De esta forma sólo obtendremos el valor (el dato) de una propiedad. Como ejemplo, si queremos que PowerShell muestre «El procesador es Intel» en caso de que el fabricante del procesador sea Intel, podemos usar el siguiente código:
1 2 3 4 5 6 7 8 |
$fabricanteProcesador = Get-WmiObject -Class Win32_Processor -ComputerName. | Select-Object -ExpandProperty Manufacturer if ( $fabricanteProcesador -like "*Intel*" ) { Write-Host ("Su procesador es Intel: {0}" -f $fabricanteProcesador) } else { Write-Host ("Su procesador es {0}" -f $fabricanteProcesador) } |
El código anterior obtendrá el valor del campo Manufacturer de la clase Win32_Processor del objeto WmiObject. Si el valor cotiene la palabra «Intel» mostrará por pantalla: Su procesador es Intel: GenuineIntel. En caso de no ser Intel mostrará «Su procesador es Valor_ Manufacturer«.
Obtener información de procesos activos en equipo Windows con WMI
Como casi siempre en PowerShell, hay numerosas formas de obtener la misma información. Usaremos la que nos interese según los datos que queramos obtener.
Para mostrar todos los datos de un proceso en ejecución podemos usar el siguiente comando PowerShell y WMI:
1 2 |
$nombrePC = "." Get-WmiObject -Class "Win32s_Process" -ComputerName $nombrePC | Format-List -Property [a,z]* |
Mostrará todos los datos sobre todos los procesos en ejecución del equipo indicado en $nombrePC, si introduciremos «.», mostrará los datos del equipo actual:
Si queremos mostrar algunos datos de algún proceso concreto, por ejemplo, para mostrar el Name, KernelModeTime, UserModeTime y ProcessID del proceso SearchIndexer.exe, podemos usar:
1 2 3 |
$nombrePC = "." $nombreProceso = "SearchIndexer.exe" Get-WmiObject -Class Win32_Process -ComputerName $strComputer | Where-Object { $_.name -eq $nombreProceso } | Format-List -Property Name, KernelModeTime, UserModeTime, ProcessID |
Otra forma de mostrar todos los datos de los procesos en ejecución, usando CIM, puede ser:
1 |
Get-CimInstance Win32_Process -Filter "name = 'smss.exe'" | fl * | more |
El comando anterior mostrará todos los datos del proceso smss.exe (uno cualquiera de ejemplo): nombre, fecha de instalación, estado, fecha de inicio del proceso, nombre del equipo donde se ejecuta, estado de ejecución, modo de tiempo del kernel, sistema operativo sobre el que se ejecuta, comando de la línea de comandos con el que se ejecutó, ruta del ejecutable, datos del uso de la memoria virtual, id de proceso, etc..
Incluso se pueden realizar acciones sobre un proceso. Por ejemplo, si queremos finalizar (cerrar) un proceso, podemos usar el siguiente código PowerShell:
1 2 3 4 5 6 7 8 9 10 |
$nombreEquipo = "." $nombreProceso = "Calculator.exe" $listaProcesos = Get-WmiObject -Class Win32_Process -ComputerName $nombreEquipo | Where-Object { $_.name -eq $nombreProceso } foreach ($procesoActual in $listaProcesos) { $procesoActual.Terminate() } |
Como ejemplo, el código anterior cerrará la calculadora de Windows (Calculator.exe) si la tenemos abierta:
Además, si tenemos los permisos suficientes, el código anterior permite cerrar procesos de equipos remotos, cambiando en $nombreEquipo el «.» por el nombre del equipo del que queramos cerrar el proceso indicado en $nombreProceso.
Y otra forma más de mostrar información de los procesos en ejecución en el equipo. En este caso, usando «», podremos hasta obtener el uso de CPU por proceso, e incluso filtrar los procesos que consuman un número de memoria RAM determinado o superior. Por ejemplo, para mostrar todos los procesos que consuma más de 200MB (200.000.000 Bytes) de RAM podemos usar:
1 |
Get-Process | Where-Object {$_.WorkingSet -gt 200000000} |
Para formatear las columnas de salida y mostrar las que queramos, incluso con el nombre que queramos, podemos usar:
1 2 3 4 |
Get-Process firefox | Format-Table ` @{Label = "WS(KB)"; Expression = {[int]($_.WS / 1024)}}, @{Label = "Tiempo CPU"; Expression = {if ($_.CPU) {$_.CPU.ToString("N")}}}, Id, ProcessName -AutoSize |
En este caso, se mostrarán todos los procesos con el nombre «firefox» y se mostrarán los WS (en Kilobytes), el tiempo de CPU, el ID de proceso y el nombre del proceso:
Todos estos comandos permiten innumerables convinaciones, tanto para mostrar la información que queramos como para filtrar y para mostrarla en el formato que queramos. Otro ejemplo de la potencia de estos comandos, para mostrar un listado de todas las ventanas abiertas en nuestro equipo y el título de cada ventana:
1 |
Get-Process | where {$_.mainWindowTitle} | Format-Table id, name, mainwindowtitle -autosize |
Obtener información de la memoria RAM del equipo con WMI y PowerShell
Continuamos con la obtención de información mediante WMI (y otros mecanismos). En este caso, para obtener todos los bancos de memoria RAM del equipo y toda la información de cada banco (módulo de memoria RAM «pinchado» en el equipo), podemos usar el siguiente comando:
1 |
Get-WmiObject Win32_PhysicalMemory | Format-List * |
Nos devolverá multitud de datos sobre la memoria RAM del equipo, por cada banco (slot/módulo), como
Para obtener sólo las columnas de datos que deseeemos e incluso formateadas, por ejemplo, para mostrar el tamaño de cada módulo en GB, podremos usar:
1 |
Get-WmiObject Win32_PhysicalMemory | Format-List @{Label = "Capacidad (GB)"; Expression = {[int]($_.Capacity/1024/1024/1024)}},BankLabel,ConfiguredClockSpeed,ConfiguredVoltage,DeviceLocator,Manufacturer |
Usando el comando anterior, si queremos obtener la RAM total, sumando la cantidad de RAM de cada banco (módulo), podemos usar:
1 2 3 4 |
$modulos = Get-WmiObject Win32_PhysicalMemory | Select-Object -ExpandProperty Capacity $totalRAM = 0 foreach ($modActual in $modulos) {$totalRAM = $totalRAM + $modActual} Write-Host "Su sistema tiene " ($modulos.count) " módulos de memoria RAM con " ($totalRAM/1024/1024/1024).ToString("F2") GB totales |
Mostrará el número de bancos (módulos) de RAM intalados en nuestro sistema y el tamaño total de la RAM en Gigabytes:
Obtener información de la placa base (motherboard) del equipo con WMI y PowerShell
Para mostrar todos los datos de la placa base del equipo (motherboard) con WMI, podemos usar el siguiente comando:
1 |
Get-WmiObject win32_baseboard | Format-List * |
Mostrará datos como la descripción, el fabricante, el modelo, número de serie, verisón, …:
Y, como siempre, para mostrar sólo los datos que nos interese (modelo, fabricante, número de serie, versión):
1 |
Get-WmiObject win32_baseboard | Format-List Product,Manufacturer,SerialNumber,Version |
Obtener información de los discos duros instalados en el equipo con WMI y PowerShell
Para mostrar todos los datos de todas las unidades de disco del equipo con WMI usaremos el siguiente comando:
1 |
Get-WmiObject -Class Win32_logicaldisk | Format-List * |
Y para mostrar sólo algunos datos (ID de unidad, nombre, comprimida, tipo, sistema de archivos, espacio libre en Bytes, tipo de medio, tamaño en Bytes, número de serie) usaremos:
1 |
Get-WmiObject -Class Win32_logicaldisk | Format-List -Property DeviceID,Caption,Compressed,DriveType,FileSystem,FreeSpace,MediaType,Name,c,VolumeSerialNumber |
Al igual que para la memoria RAM, si queremos por ejemplo obtener el tamaño total en Terabytes (TB) de todos los discos duros (dispositivos de almacenamiento) de nuestro equipo, podemos usar el siguiente código PowerShell:
1 2 3 4 |
$unidadesHD = Get-WmiObject Win32_logicaldisk | Select-Object -ExpandProperty Size $totalHD = 0 foreach ($unActual in $unidadesHD) {$totalHD = $totalHD + $unActual} Write-Host "Su sistema tiene " ($unidadesHD.count) " unidades de almacenamiento con " ($totalHD/1024/1024/1024/1024).ToString("F2") TB totales |
Obtener aplicaciones instaladas en el equipo con WMI y PowerShell
Para obtener una lista de las aplicaciones instaladas en el equipo, cuyo nombre contenga la palabra «MySQL», mostrando el nombre de la aplicación, la versión, la fecha de instalación y el fabricante, podemos usar el siguiente comando:
1 |
Get-WmiObject -Class Win32_Product | Where-Object {$_.name -Like "*MySQL*"} | Format-List -Property Name,Version,InstallDate,Vendor |