WMI e CIM
Nesta aula, você aprenderá a diferença entre WMI e CIM, como usar o cmdlet Get-CimInstance para consultar informações do sistema de forma eficiente e moderna, e verá exemplos práticos de consultas úteis no dia a dia.
Bem-vindo à aula sobre WMI e CIM no PowerShell! Nesta aula, vamos explorar dois conceitos fundamentais para administração de sistemas Windows: WMI (Windows Management Instrumentation) e CIM (Common Information Model). Entender a diferença entre eles e saber usar o cmdlet Get-CimInstance é essencial para automatizar tarefas de gerenciamento, coleta de informações e monitoramento de ambientes Windows.
O WMI é a implementação da Microsoft do padrão CIM, que permite acessar informações de hardware, software e configuração do sistema. Por muitos anos, os administradores usavam cmdlets como Get-WmiObject para consultar essas informações. No entanto, o PowerShell trouxe uma abordagem mais moderna e eficiente com o Get-CimInstance, que usa o protocolo WS-Management e é compatível com sistemas não Windows. Vamos mergulhar nesse mundo e aprender a usar essas ferramentas de forma prática.
Get-CimInstance
O cmdlet Get-CimInstance é a forma recomendada de consultar informações do sistema no PowerShell moderno. Ele faz parte do módulo CimCmdlets e usa o padrão CIM, que é um padrão aberto para representação de informações de gerenciamento. Diferente do Get-WmiObject, que usa a tecnologia DCOM, o Get-CimInstance usa o protocolo WS-Management (WSMan), que é mais leve, seguro e funciona tanto em máquinas locais quanto remotas, inclusive com sistemas Linux e macOS que tenham o Open Management Infrastructure (OMI) instalado.
Uma das principais vantagens do Get-CimInstance é que ele retorna objetos com metadados mais ricos, permitindo que você use a pipeline do PowerShell de forma mais eficiente. Além disso, ele suporta operações assíncronas e a possibilidade de criar classes CIM personalizadas. Vamos ver como usá-lo na prática.
# Sintaxe básica para consultar informações da BIOS
Get-CimInstance -ClassName Win32_BIOSO parâmetro -ClassName é obrigatório e especifica a classe CIM que você deseja consultar. Existem milhares de classes disponíveis, como Win32_Process, Win32_OperatingSystem, Win32_ComputerSystem, entre outras. Você também pode usar o parâmetro -Namespace para especificar um namespace diferente do padrão (root/cimv2).
Outra funcionalidade importante é o parâmetro -Filter, que permite filtrar os resultados de forma semelhante a uma consulta SQL. Por exemplo, para listar apenas processos com mais de 100 MB de memória:
Get-CimInstance -ClassName Win32_Process | Where-Object { $_.WorkingSetSize -gt 100MB }Ou usando o filtro diretamente:
Get-CimInstance -ClassName Win32_Process -Filter "WorkingSetSize > 104857600"O Get-CimInstance também permite consultas remotas usando o parâmetro -ComputerName. Isso é especialmente útil para administrar vários servidores sem precisar de sessões separadas.
Consultando o sistema
Vamos explorar alguns exemplos práticos de consultas ao sistema usando o Get-CimInstance. Essas consultas são comuns no dia a dia de um administrador de sistemas.
1. Informações do sistema operacional:
Get-CimInstance -ClassName Win32_OperatingSystem | Select-Object Caption, Version, BuildNumber, OSArchitectureIsso retorna o nome do sistema operacional, versão, número de build e arquitetura.
2. Informações de hardware:
Get-CimInstance -ClassName Win32_ComputerSystem | Select-Object Manufacturer, Model, TotalPhysicalMemory, NumberOfProcessorsMostra fabricante, modelo, memória total e número de processadores.
3. Listar serviços e seus estados:
Get-CimInstance -ClassName Win32_Service | Select-Object Name, State, StartMode, PathNameLista todos os serviços, indicando se estão em execução ou parados, o tipo de inicialização e o caminho do executável.
4. Discos e volumes:
Get-CimInstance -ClassName Win32_LogicalDisk -Filter "DriveType=3" | Select-Object DeviceID, VolumeName, Size, FreeSpaceO filtro DriveType=3 seleciona apenas discos locais fixos. Você pode ver o espaço total e livre de cada partição.
5. Processos em execução:
Get-CimInstance -ClassName Win32_Process | Select-Object Name, ProcessId, WorkingSetSize, ExecutablePath | Sort-Object WorkingSetSize -Descending | Select-Object -First 5Lista os cinco processos que mais consomem memória.
Esses exemplos mostram como é fácil obter informações detalhadas do sistema com apenas algumas linhas de código. O Get-CimInstance é muito mais eficiente e flexível do que os cmdlets antigos.
vs WMI legado
Se você já trabalhou com PowerShell, provavelmente conhece o Get-WmiObject, que era o cmdlet padrão para consultas WMI até o PowerShell 5.1. No entanto, a Microsoft recomenda o uso do Get-CimInstance em vez do Get-WmiObject por várias razões:
- Protocolo:
Get-WmiObjectusa DCOM, que é pesado e pode ser bloqueado por firewalls.Get-CimInstanceusa WS-Management (WSMan), que é baseado em HTTP/HTTPS e mais fácil de configurar em redes. - Compatibilidade: O CIM é um padrão aberto, então o
Get-CimInstancepode ser usado para consultar sistemas que não sejam Windows, como Linux com OMI. - Performance: O
Get-CimInstanceé geralmente mais rápido e consome menos recursos, especialmente em consultas remotas. - Extensibilidade: O CIM permite criar classes personalizadas e usar provedores mais modernos.
- Suporte futuro: O
Get-WmiObjectfoi removido no PowerShell 7, portanto, scripts que o usam não funcionarão em versões novas. OGet-CimInstanceé o futuro.
Embora o Get-WmiObject ainda funcione em versões anteriores ao PowerShell 7, é importante migrar seus scripts para o Get-CimInstance agora. A sintaxe é muito semelhante, mas alguns parâmetros mudaram. Por exemplo, no Get-WmiObject, o filtro era passado com o parâmetro -Filter, e no Get-CimInstance também, mas os valores podem ser ligeiramente diferentes. Além disso, o Get-CimInstance retorna objetos com propriedades que podem ser acessadas de forma mais consistente.
Vamos comparar uma consulta nos dois cmdlets:
# WMI legado
Get-WmiObject -Class Win32_Process -Filter "Name='powershell.exe'" | Select-Object Name, ProcessId
# CIM moderno
Get-CimInstance -ClassName Win32_Process -Filter "Name='powershell.exe'" | Select-Object Name, ProcessIdOs resultados são os mesmos, mas o segundo é o recomendado. Para facilitar a migração, você pode usar o módulo CimCmdlets que oferece aliases como gcim para Get-CimInstance.
Exemplos
Vamos colocar em prática tudo o que aprendemos com exemplos mais complexos e úteis.
Exemplo 1: Relatório de hardware completo
Crie um script que coleta informações do processador, memória, disco e sistema operacional e gera um relatório formatado.
$computer = Get-CimInstance -ClassName Win32_ComputerSystem
$os = Get-CimInstance -ClassName Win32_OperatingSystem
$cpu = Get-CimInstance -ClassName Win32_Processor
$disk = Get-CimInstance -ClassName Win32_LogicalDisk -Filter "DriveType=3"
$report = [PSCustomObject]@{
ComputerName = $computer.Name
Manufacturer = $computer.Manufacturer
Model = $computer.Model
OS = $os.Caption
Version = $os.Version
CPU = $cpu.Name
TotalRAM = [math]::Round($computer.TotalPhysicalMemory / 1GB, 2)
DiskSpace = ($disk | ForEach-Object { "$($_.DeviceID) $([math]::Round($_.FreeSpace / 1GB, 2)) GB free of $([math]::Round($_.Size / 1GB, 2)) GB" }) -join "; "
}
$report | Format-ListExemplo 2: Verificar se um serviço está em execução
$serviceName = "Spooler"
$service = Get-CimInstance -ClassName Win32_Service -Filter "Name='$serviceName'"
if ($service.State -eq "Running") {
Write-Host "O serviço $serviceName está em execução."
} else {
Write-Host "O serviço $serviceName não está em execução. Estado atual: $($service.State)"
}Exemplo 3: Consulta remota a vários computadores
Você pode usar o parâmetro -ComputerName para consultar vários servidores de uma vez. Vamos verificar o espaço em disco de uma lista de servidores.
$servers = @("SERVER01", "SERVER02", "SERVER03")
foreach ($server in $servers) {
try {
$disk = Get-CimInstance -ClassName Win32_LogicalDisk -ComputerName $server -Filter "DriveType=3"
foreach ($d in $disk) {
[PSCustomObject]@{
Server = $server
Drive = $d.DeviceID
FreeSpaceGB = [math]::Round($d.FreeSpace / 1GB, 2)
TotalSpaceGB = [math]::Round($d.Size / 1GB, 2)
}
}
} catch {
Write-Warning "Falha ao consultar $server : $_"
}
}Exemplo 4: Criar uma classe CIM personalizada
O CIM permite criar classes personalizadas para armazenar informações. Vamos criar uma classe para representar um usuário do sistema.
# Criar uma classe CIM personalizada
New-CimInstance -ClassName My_User -Namespace root/cimv2 -Property @{
Name = "João Silva"
Age = 30
Email = "joao@example.com"
}
# Recuperar a classe
Get-CimInstance -ClassName My_UserIsso cria uma instância da classe My_User no namespace root/cimv2. Você pode usar essa técnica para armazenar dados de configuração personalizados.
Exemplo 5: Monitorar eventos do sistema
Você pode usar o Register-CimIndicationEvent para monitorar eventos, como a criação de um processo. Vamos monitorar quando o Bloco de Notas for aberto.
Register-CimIndicationEvent -ClassName Win32_ProcessStartTrace -SourceIdentifier "ProcessStarted" -Action {
$event = $event.SourceEventArgs.NewEvent
if ($event.ProcessName -eq "notepad.exe") {
Write-Host "Bloco de Notas iniciado com PID $($event.ProcessID)"
}
}
# Para parar o monitoramento, use:
# Unregister-Event -SourceIdentifier "ProcessStarted"Esses exemplos mostram a versatilidade do Get-CimInstance e do CIM. Agora você pode explorar ainda mais as possibilidades.
Boas práticas
Ao trabalhar com CIM, siga estas boas práticas para garantir eficiência e segurança:
- Prefira sempre
Get-CimInstanceem vez deGet-WmiObjectem scripts novos. - Use o parâmetro
-Filterpara filtrar no servidor, em vez de trazer todos os objetos e filtrar no cliente. Isso reduz o tráfego de rede e melhora a performance. - Use
-ComputerNamepara consultas remotas, mas lembre-se de configurar corretamente o WinRM (Windows Remote Management) e as permissões de firewall. - Quando precisar de informações específicas, selecione apenas as propriedades necessárias com
Select-Objectpara reduzir a quantidade de dados transferidos. - Para consultas complexas, considere usar
Get-CimInstancecom a classeWin32_*adequada e, se necessário, use a sintaxe de consulta WQL (WMI Query Language) com o parâmetro-Query. - Teste seus scripts em um ambiente de laboratório antes de executar em produção.
Referências
- Documentação oficial do Get-CimInstance
- WMI (Windows Management Instrumentation) - Documentação da Microsoft
- Classes Win32 - Documentação da Microsoft
- Criando comandos Get-CimInstance - Microsoft Learn
- Consultas WQL - Documentação da Microsoft
- Módulo CimCmdlets - Microsoft Learn
Exercícios
- Escreva um comando PowerShell que use
Get-CimInstancepara listar todos os serviços que estão em execução no momento, exibindo apenas o nome e o caminho do executável. - Como você faria para obter a quantidade total de memória física do computador usando
Get-CimInstance? Escreva o comando. - Qual é a diferença principal entre
Get-WmiObjecteGet-CimInstance? Explique em termos de protocolo. - Escreva um script que consulte o espaço livre em disco de todos os discos fixos locais e exiba uma mensagem de alerta se o espaço livre for menor que 10 GB.
- Explique como você faria para consultar informações de um computador remoto usando
Get-CimInstance. Inclua os parâmetros necessários.
Get-CimInstance -ClassName Win32_Service -Filter "State='Running'" | Select-Object Name, PathNameGet-CimInstance -ClassName Win32_ComputerSystem | Select-Object TotalPhysicalMemoryGet-WmiObject usa o protocolo DCOM, enquanto o Get-CimInstance usa o protocolo WS-Management (WSMan). O WSMan é mais leve, seguro e funciona melhor em redes, além de ser compatível com sistemas não Windows.$disks = Get-CimInstance -ClassName Win32_LogicalDisk -Filter "DriveType=3"
foreach ($disk in $disks) {
$freeGB = [math]::Round($disk.FreeSpace / 1GB, 2)
if ($freeGB -lt 10) {
Write-Warning "Disco $($disk.DeviceID) com apenas $freeGB GB livres!"
} else {
Write-Host "Disco $($disk.DeviceID) tem $freeGB GB livres."
}
}-ComputerName com o nome ou IP do computador. Por exemplo: Get-CimInstance -ClassName Win32_OperatingSystem -ComputerName "SERVER01" É necessário que o WinRM esteja habilitado na máquina remota e que você tenha permissões adequadas.