PowerShell WMI: Automatiser les tâches Windows

La Gestion des instruments Windows (WMI) existe depuis longtemps sous Windows. De nombreux professionnels de l’informatique ont utilisé WMI soit directement, soit via des outils qui lisent des informations à partir de WMI. Saviez-vous que les cmdlets WMI de PowerShell sont intégrés ?

WMI est l’endroit par défaut pour recueillir des informations sur une machine Windows et pour manipuler divers services à l’intérieur de Windows. En raison de la vaste gamme d’informations de WMI, vous pouvez y accéder en utilisant Powershell WMI. Utiliser PowerShell pour interroger WMI vous permet d’automatiser des milliers de tâches sur les ordinateurs Windows.

Heureusement, l’un des premiers systèmes dans Windows pour lesquels PowerShell disposait de commandes était WMI. Comme vous disposez des cmdlets natifs PowerShell WMI, cela signifiait qu’un administrateur informatique pouvait tirer parti de la syntaxe verbe/nom facile à comprendre de PowerShell pour interagir avec WMI et, comme vous le verrez, les utilisateurs avancés peuvent également invoquer des événements et des classes WMI directement en utilisant simplement des commandes PowerShell standard.

Cmdlets PowerShell WMI vs CIM

Il existe deux « ensembles » de commandes pour utiliser WMI dans PowerShell. Certaines personnes appellent ces « ensembles » la manière « ancienne » d’interagir avec WMI et les cmdlets CIM. Lors de la requête d’informations à partir de WMI, les deux renvoient les mêmes informations mais les abordent un peu différemment. La manière « ancienne » de lire les informations à partir de WMI consiste à utiliser la commande Get-WmiObject. D’autres cmdlets WMI incluent Invoke-WmiMethod, Register-WMIEvent et ainsi de suite, mais nous ne les couvrirons pas dans notre article.

La cmdlet PowerShell WMI Get-WmiObject fonctionne, mais elle présente un inconvénient majeur. Lors de l’interrogation d’ordinateurs distants, elle dépend de DCOM, qui a historiquement été une vecteur d’attaque. DCOM est généralement bloqué par divers pare-feu. Étant donné que c’est la « vieille » méthode, nous n’allons pas explorer cette approche. À la place, nous nous concentrerons sur les cmdlets CIM, principalement Get-CimInstance.

DCOM Component Services

La grande différence entre Get-WmiObject et Get-CimInstance est qu’au lieu d’utiliser DCOM pour accéder aux ordinateurs distants, Get-CimInstance utilise le protocole WSMAN, qui est le transport pour la fonctionnalité familière de l’accès à distance PowerShell.

Cmdlets CIM PowerShell

Disons que vous souhaitez obtenir des informations sur la version de Windows sur un ordinateur distant. Dans ce cas, je voudrais voir des informations provenant d’un ordinateur appelé DC. Vous pouvez le faire en spécifiant la classe WMI qui contient les informations et le nom de l’ordinateur que je souhaite interroger.

Vous pouvez voir ci-dessous que, comme Get-CimInstance n’affiche pas, par défaut, tous les attributs à l’intérieur de la classe, j’ai dû rediriger la sortie vers la commande Select-Object pour afficher toutes les propriétés.

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 seulement vous pouvez recueillir des informations via les propriétés, mais vous pouvez également invoquer des méthodes WMI/CIM sur les classes également. Un bon exemple en est l’arrêt d’un processus sur un ordinateur distant. Nativement, il n’y a aucun moyen de le faire via la commande Stop-Process dans PowerShell. Cependant, il existe un moyen via une requête WMI. Pour tuer des processus à distance, nous devons d’abord déterminer le processus que nous aimerions tuer. Nous pouvons énumérer tous les processus en cours d’exécution sur un ordinateur distant en examinant 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

Une fois que vous avez déterminé quel processus tuer, vous pouvez ensuite passer le nom à la méthode Terminate() sur la classe Win32_Process. Pour cela, vous devez capturer une instance du processus que vous souhaitez tuer.

Remarquez ci-dessous que j’utilise le paramètre Filter pour m’assurer de ne recevoir que le processus ccmexec.exe. C’est important !

Une fois que vous avez capturé l’instance, vous pouvez ensuite invoquer la méthode Terminate() pour tuer le processus en utilisant la commande Invoke-CimMethod comme indiqué ci-dessous.

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

Résumé

Si vous souhaitez en savoir plus sur l’utilisation de WMI dans PowerShell et notamment sur l’utilisation du cmdlet PowerShell WMI Get-WmiObject qui n’a pas été couvert ici, je vous encourage à consulter Get-WmiObject: Interrogation de WMI sur des ordinateurs locaux et distants où je vais plus en profondeur dans WMI et utilise le cmdlet Get-WmiObject.

Pour une description complète de tous les cmdlets CIM et de leur fonctionnement dans PowerShell, consultez l’article Introduction aux cmdlets CIM sur Technet. Vous y trouverez tous les différents cmdlets CIM et comment ils pourraient être utilisés dans vos scripts.

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