PowerShell WMI: Automatizar Tarefas no Windows

O Windows Management Instrumentation (WMI) está presente no Windows há muito tempo. Muitos profissionais de TI já utilizaram o WMI diretamente ou ferramentas que leem informações do WMI. Você sabia que os cmdlets do PowerShell para WMI já vêm embutidos?

O WMI é o local padrão para reunir informações sobre uma máquina Windows e manipular vários serviços dentro do Windows. Devido à vasta gama de informações do WMI, você pode utilizá-lo com o PowerShell. Usar o PowerShell para interrogar o WMI permite automatizar milhares de tarefas em computadores Windows.

Felizmente, um dos primeiros sistemas no Windows para os quais o PowerShell tinha comandos foi o WMI. Como você tem cmdlets nativos do PowerShell para WMI, isso significava que um administrador de TI poderia aproveitar a sintaxe de verbo/substantivo de fácil entendimento do PowerShell para interagir com o WMI e, como verá, usuários avançados também podem invocar eventos e classes do WMI diretamente apenas usando comandos padrão do PowerShell.

Cmdlets do PowerShell para WMI vs CIM

Há dois “conjuntos” de comandos quando se trata de usar o WMI no PowerShell. Algumas pessoas se referem a esses “conjuntos” como a maneira “antiga” de interagir com o WMI e os cmdlets CIM. Ao consultar informações do WMI, ambos retornam as mesmas informações, mas abordam isso um pouco diferente. A maneira “antiga” de ler informações do WMI é usando o comando Get-WmiObject. Outros cmdlets do WMI incluem Invoke-WmiMethod, Register-WMIEvent e assim por diante, mas não abordaremos isso em nosso artigo.

O cmdlet WMI do PowerShell, Get-WmiObject, funciona, mas possui uma séria desvantagem. Ao consultar computadores remotos, ele depende do DCOM, que historicamente tem sido um vetor de ataque. O DCOM geralmente é bloqueado por vários firewalls. Como este é o método “antigo”, não vamos abordar esta abordagem. Em vez disso, vamos nos concentrar nos cmdlets CIM, principalmente Get-CimInstance.

DCOM Component Services

A grande diferença entre Get-WmiObject e Get-CimInstance é que, em vez de usar o DCOM para acessar computadores remotos, Get-CimInstance utiliza o protocolo WSMAN, que é o transporte para a conhecida funcionalidade de remoção do PowerShell.

Cmdlets CIM do PowerShell

Vamos supor que você queira obter algumas informações sobre a versão do Windows em um computador remoto. Neste caso, gostaria de ver algumas informações de um computador chamado DC. Você pode fazer isso especificando a classe WMI que contém as informações e o nome do computador que desejo consultar.

Como pode ser visto abaixo, como o Get-CimInstance não exibe, por padrão, todos os atributos dentro da classe, foi necessário redirecionar a saída para o comando Select-Object para retornar todas as propriedades.

PS> Get-CimInstance -ClassName Win32_OperatingSystem -ComputerName DC | Select *
Status                                    : OK
Name                                      : Microsoft Windows 10 Pro|C:\WINDOWS|\Device\Harddisk0\Partition2
FreePhysicalMemory                        : 1802336
FreeSpaceInPagingFiles                    : 800308
FreeVirtualMemory                         : 1472916
Caption                                   : Microsoft Windows 2016
Description                               :
InstallDate                               : 7/5/2018 6:04:09 PM
CreationClassName                         : Win32_OperatingSystem
CSCreationClassName                       : Win32_ComputerSystem
--snip-

Não apenas é possível reunir informações por meio de propriedades, mas também é possível invocar métodos WMI/CIM em classes. Um bom exemplo disso é interromper um processo em um computador remoto. Nativamente, não há uma maneira de fazer isso via comando Stop-Process no PowerShell. No entanto, há uma maneira via consulta WMI. Para encerrar processos remotos, primeiro precisamos descobrir qual processo gostaríamos de encerrar. Podemos enumerar todos os processos em execução em um computador remoto observando a classe Win32_Process.

PS> Get-CimInstance -ClassName CIM_Process -ComputerName DC

ProcessId Name                                      HandleCount WorkingSetSize VirtualSize   PSComputerName
--------- ----                                      ----------- -------------- -----------   --------------
0         System Idle Process                       0           4096           65536         DC
4         System                                    631         212992         3465216       DC
232       smss.exe                                  52          823296         4325376       DC
328       csrss.exe                                 258   om      3346432        49483776      DC
392       csrss.exe                                 87          2789376        44507136      DC
400       wininit.exe                               80          3072000        2199065096192 DC
428       winlogon.exe                              119         4431872        2199079510016 DC

Depois de descobrir qual processo encerrar, você pode passar o nome para o método Terminate() na classe Win32_Process. Para fazer isso, você precisa capturar uma instância do processo que deseja encerrar.

Observe abaixo que estou usando o parâmetro Filter para garantir que receba apenas o processo ccmexec.exe. Isso é importante!

Depois de capturar a instância, você pode então invocar o método Terminate() para encerrar o processo usando o comando Invoke-CimMethod, conforme mostrado abaixo.

PS> $instance = Get-CimInstance -ClassName CIM_Process -ComputerName DC -Filter 'Name = "ccmexec.exe"'
PS> $instance

ProcessId Name        HandleCount WorkingSetSize VirtualSize PSComputerName
--------- ----        ----------- -------------- ----------- --------------
3528      CcmExec.exe 878         34246656       158261248   DC


PS> Invoke-CimMethod -InputObject $instance -MethodName Terminate

ReturnValue PSComputerName
----------- --------------
          0 DC

Resumo

Se deseja aprender mais sobre o uso de WMI no PowerShell, especialmente usando o cmdlet WMI do PowerShell Get-WmiObject que não foi abordado aqui, recomendo verificar Get-WmiObject: Consultando WMI em Computadores Locais e Remotos, onde aprofundo no WMI e utilizo o cmdlet Get-WmiObject.

Para obter uma análise completa de todos os cmdlets CIM e como eles funcionam no PowerShell, consulte o artigo Introdução aos Cmdlets CIM no Technet. Lá você verá todos os vários cmdlets CIM e como podemPara ser usados em seus scripts ob.ter uma análise completa de todos os cmdlets CIM e como eles funcionam no PowerShell, consulte o artigo Introdução aos Cmdlets CIM no Technet. Lá você verá todos os diversos cmdlets CIM e como podem ser usados em seus scripts.

Source:
https://adamtheautomator.com/powershell-wmi/