PowerShell WMI: Automatizzare le attività di Windows

Windows Management Instrumentation (WMI) esiste da molto tempo in Windows. Molti professionisti IT hanno utilizzato WMI direttamente o hanno utilizzato strumenti che leggono informazioni da WMI. Sai che i cmdlet di PowerShell per WMI sono integrati?

WMI è il luogo di riferimento per raccogliere informazioni su una macchina Windows e per manipolare vari servizi all’interno di Windows. Grazie alla vasta gamma di informazioni di WMI, è possibile sfruttare PowerShell per WMI. Utilizzando PowerShell per interrogare WMI, è possibile automatizzare migliaia di attività su computer Windows.

Fortunatamente, uno dei primi sistemi di Windows per cui PowerShell aveva comandi era WMI. Poiché hai i cmdlet di PowerShell nativi per WMI, ciò significava che un amministratore IT poteva sfruttare la sintassi dei verbi/sostantivi di PowerShell facile da comprendere per interagire con WMI e, come vedrai, gli utenti esperti possono anche richiamare eventi e classi di WMI direttamente utilizzando semplici comandi di PowerShell.

Cmdlet di PowerShell per WMI vs CIM

Ci sono due “insiemi” di comandi quando si tratta di utilizzare WMI in PowerShell. Alcune persone si riferiscono a questi “insiemi” come al modo “vecchio” di interagire con WMI e ai cmdlet CIM. Quando si interrogano informazioni da WMI, entrambi restituiscono le stesse informazioni ma le affrontano in modo leggermente diverso. Il modo “vecchio” di leggere informazioni da WMI è utilizzando il comando Get-WmiObject. Altri cmdlet di WMI includono Invoke-WmiMethod, Register-WMIEvent e così via, ma non li copriremo nel nostro articolo.

Il cmdlet PowerShell WMI Get-WmiObject funziona ma ha un grave inconveniente. Quando si interrogano computer remoti, si basa su DCOM e storicamente DCOM è stato un vettore di attacco per i cattivi. Di solito DCOM è bloccato da vari firewall. Poiché questo è il “vecchio” metodo, non entreremo in questo metodo. Invece, ci concentreremo sui cmdlet CIM: principalmente, Get-CimInstance.

DCOM Component Services

La grande differenza tra Get-WmiObject e Get-CimInstance è che invece di utilizzare DCOM per accedere a computer remoti, Get-CimInstance utilizza il protocollo WSMAN che è il trasporto per la familiare funzionalità PowerShell remoting.

Cmdlet CIM di PowerShell

Supponiamo che tu voglia restituire alcune informazioni sulla versione di Windows su un computer remoto. In questo caso, vorrei vedere alcune informazioni da un computer chiamato DC. Puoi farlo specificando la classe WMI che contiene le informazioni e il nome del computer che desidero interrogare.

Puoi vedere qui sotto che poiché Get-CimInstance non visualizza, per impostazione predefinita, tutti gli attributi all’interno della classe, ho dovuto indirizzare l’output al comando Select-Object per restituire tutte le proprietà.

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-

Non solo è possibile raccogliere informazioni tramite le proprietà, ma è anche possibile invocare metodi WMI/CIM sulle classi. Un buon esempio di questo è fermare un processo su un computer remoto. Nativamente, non c’è modo di farlo tramite il comando Stop-Process in PowerShell. Tuttavia, c’è un modo tramite query WMI. Per terminare i processi remoti, prima dobbiamo capire quale processo vogliamo terminare. Possiamo enumerare tutti i processi in esecuzione su un computer remoto guardando la 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

Una volta individuato il processo da terminare, è possibile passare il nome al metodo Terminate() sulla classe Win32_Process. Per fare ciò, è necessario catturare un’istanza del processo che si desidera terminare.

Nota qui sotto che sto utilizzando il parametro Filter per assicurarmi di ricevere solo il processo ccmexec.exe. Questo è importante!

Una volta catturata l’istanza, è possibile invocare il metodo Terminate() per terminare il processo utilizzando il comando Invoke-CimMethod come mostrato di seguito.

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

Riepilogo

Se desideri approfondire l’uso di WMI in PowerShell e soprattutto l’uso del cmdlet PowerShell WMI Get-WmiObject che non è stato trattato qui, ti incoraggio a dare un’occhiata a Get-WmiObject: Interrogazione di WMI su Computer Locali e Remoti dove approfondisco WMI e uso il cmdlet Get-WmiObject.

Per una completa panoramica di tutti i cmdlet CIM e di come funzionano in PowerShell, fare riferimento all’articolo Introduzione ai cmdlet CIM su Technet. Lì troverai tutti i vari cmdlet CIM e come potrebbero essere utilizzati nei tuoi script.

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