Vous êtes-vous déjà demandé pourquoi une liste des mises à jour Windows installées est générée? Et par quelle API pour l'obtenir? J'essaierai de donner des réponses à ces questions et à d'autres questions émergentes dans ma petite étude.

Contexte ou comment tout a commencé.
Chaque année, une conférence de jeunes spécialistes est organisée
dans notre entreprise , où chaque participant peut résoudre le problème d'un département (une liste de sujets est proposée à l'avance). Et le département de SPAS (maintenance des logiciels et du matériel) avait la tâche suivante, ce qui m'a intéressé, en plus il a permis de revenir à la programmation (malheureusement, pour le moment je travaille dans cette entreprise en tant que simple opérateur de NPPS).
Auparavant, pour chaque «TO» avec l'aide de WSUS, toutes les mises à jour publiées étaient récupérées et distribuées à toutes les machines. Des BST (bulletins de service technique) sont également apparus périodiquement, ce qui indiquait qu'il était nécessaire d'installer les mises à jour nécessaires sous la forme de packages isolés. Par conséquent, nous accumulons des mises à jour qui ne peuvent pas être suivies dans WSUS, mais qui ne peuvent être vues que via le panneau de configuration dans la section "Mises à jour installées".

Il y a des situations où le poste de travail ou le serveur "plante" et vous devez le restaurer à partir d'une image créée il y a quelque temps. Lors de la récupération à partir d'une image, il est possible que nous perdions les mises à jour dont nous avons besoin (qui se présentaient sous la forme de packages isolés) qui ont été installées avant que la machine ne plante. Expliqué le plus en détail possible, car les clarifications seront déjà un secret commercial.
C'est pourquoi l'idée est venue de créer un programme qui pourrait extraire cette liste de mises à jour (de préférence à
distance sur le réseau local), écrire dans un fichier / base de données, comparer la liste actuelle avec un certain modèle et envoyer un message au système SCADA via l'un des protocoles - SNMP, OPC.
Comme vous l'avez peut-être deviné d'après le titre de l'article, j'ai déjà eu du mal à choisir la méthode de récupération de la liste. Comme d'habitude, j'ai décidé de rechercher la bonne dans le moteur de recherche, posé des questions sur les ressources spécialisées (
un ,
deux , pour une raison quelconque, stackoverflow en anglais n'aimait pas ma question et a dû être supprimé), mais toutes les réponses n'ont pas donné le résultat souhaité. Par conséquent, j'ai dû le découvrir moi-même, ce qui sera discuté plus tard.
Commandes de la console
Commençons par un simple et profitons de ce que Windows nous offre sans utiliser d'outils tiers. Cela peut être fait en utilisant les commandes suivantes:
- liste wmic qfe
- systeminfo
- dism / online / get-packages
- via PowerShell:
- Obtenez le correctif
- Get-SilWindowsUpdate (uniquement disponible dans les éditions serveur)
- Get-WmiObject -Class win32_quickfixengineering - via l'accès à la classe WMI win32_quickfixengineering (à propos de WMI un peu plus tard)
Vous pouvez obtenir la liste via l'interface graphique via l'élément standard du Panneau de configuration «Ajout / Suppression de programmes», mais nous ne pouvons rien copier à partir de là. Chaque outil du panneau de configuration est représenté par un fichier .cpl dans le dossier Windows \ System. Les fichiers .Cpl du dossier système Windows sont automatiquement téléchargés au démarrage du panneau de configuration. Le fichier Appwiz.cpl est responsable de l'élément de programme. Son analyse n'a abouti à rien.
La sortie de la commande console peut être redirigée vers un fichier puis elle peut être analysée, mais c'est faux, plus un appel de programme (selon les règles SB, cela ne fonctionnera pas) et il n'est pas question de recevoir la liste à distance. Par conséquent, je vous suggère d'appeler simplement les commandes, de comparer le nombre de mises à jour dans chaque liste, avec la liste via le Panneau de configuration et de poursuivre notre enquête.
Formellement, toutes les méthodes pour obtenir la liste des mises à jour peuvent être divisées en deux groupes: local et réseau.

Toutes les méthodes ont été testées sur des images système propres (Windows 7, 8, Server 2012 R2) avec des mises à jour intégrées, après chaque mise à jour via le centre de mise à jour à partir des serveurs officiels de Microsoft, une vérification supplémentaire a été effectuée. Arrêtons-nous sur chacun d'eux plus en détail.
WUA
WUApi (API Windows Update Agent) - Utilisation de l'API Windows Update Agent. L'option la plus évidente, dont le nom parle de lui-même. Nous utiliserons la bibliothèque Wuapi.dll pour cela.
Remarque: ci-après, pour ma commodité, je vais insérer tous les résultats dans la liste. Ce n'est peut-être pas rationnel, mais cela m'a paru une bonne idée.
Exemple d'implémentationusing WUApiLib; public static List<string> listUpdateHistory() {
Il existe une deuxième variante de cette méthode:
Update Session - recevoir des informations en se connectant à la session de mise à jour de Windows Update Agent (dans ce cas, nous ne travaillons pas directement avec la bibliothèque).
Exemple d'implémentation public static List<string> Sessionlist(string pc) { List<string> result = new List<string>(50);
Microsoft suggère l'
utilisation à distance
de l'API .
Les principaux inconvénients de ces deux méthodes sont qu'elles ne vous permettent pas de trouver des correctifs KB qui ne sont pas distribués via Windows Update. Vous ne pouvez voir que ce qui s'est passé par l'agent de mise à jour lui-même, c'est-à-dire que cette option ne nous convient pas.
DISM
Deployment Image Servicing and Management est un outil de ligne de commande qui peut être utilisé pour gérer une image Windows ou pour préparer une image d'un environnement de préinstallation Windows (Windows PE). Il remplace le gestionnaire de packages (Pkgmgr.exe), PEimg et Intlcfg.
Cet utilitaire est utilisé pour intégrer des mises à jour, des service packs dans l'image système. Les mises à jour Windows sont des modules distincts qui peuvent être présentés de plusieurs manières:
- Fichiers .cab (Cabinet) - archives. Conçu pour la distribution et l'installation à l'aide de modules Windows Update en mode automatisé;
- Fichiers .msu (Microsoft Update Standalone Package) - fichiers exécutables. Conçu pour la distribution et l'installation par les utilisateurs eux-mêmes en mode manuel via le catalogue de mise à jour Microsoft. En fait, il s'agit d'un ensemble packagé composé de fichiers .cab-, .xml, .txt.
La commande
dism / online / get-packages mentionnée précédemment affiche des informations de base sur tous les packages dans l'image wim / le système actuel. Microsoft a pris soin de nous et fournit des
packages NuGet pour une utilisation pratique de l'API.
Exemple d'implémentation using Microsoft.Dism; public static List<string> DISMlist() { List<string> result = new List<string>(220); try { DismApi.Initialize(DismLogLevel.LogErrors); var dismsession = DismApi.OpenOnlineSession(); var listupdate = DismApi.GetPackages(dismsession); int ab = listupdate.Count;
Le nombre de mises à jour a coïncidé avec le nombre de la liste du Panneau de configuration jusqu'à la première mise à jour via le centre de contrôle - après cela, le nombre de mises à jour est devenu moins (il était de 214, il est devenu de 209), bien que logiquement elles devraient augmenter. Exemples de sortie
Avant la mise à jour ,
Après la mise à jour .
Quelle est la raison de cela, je ne peux que spéculer - peut-être que certaines mises à jour ont remplacé les précédentes, par conséquent, le nombre est devenu moins.
Un peu plus tard, je suis tombé sur un utilitaire du
DISM ++ chinois, qui n'est pas basé sur l'API DISM ou l'API DISM Core, mais les bibliothèques dont il dispose n'ont pas les méthodes dont j'ai besoin pour ouvrir, j'ai donc abandonné cette idée et j'ai poursuivi ma recherche.
WSUS
Windows Server Update Services (
WSUS ) est un serveur de mise à jour des systèmes d'exploitation et des produits Microsoft. Le serveur de mise à jour se synchronise avec le site Web de Microsoft, téléchargeant des mises à jour pouvant être distribuées sur le réseau local de l'entreprise. Encore une fois, un outil spécial conçu pour fonctionner avec les mises à jour.
Distribué uniquement sur les éditions serveur de Windows, le support suivant a donc été déployé:
- le système principal est Windows Server 2016;
- et grâce au système de virtualisation Hyper-V, deux systèmes d'exploitation clients ont été déployés:
Tous les systèmes sont connectés à un seul réseau local virtuel, mais
sans accès à Internet .
Quelques conseilsAfin de ne pas allouer de partition de disque dur pour le nouveau système, j'utilise
WinNTSetup et
j'installe le système sur des disques VHD - le chargeur de démarrage, à partir de Windows 7 (éditions Professional / Ultimate), fait un excellent travail de démarrage à partir d'une image disque. Les disques ainsi obtenus peuvent être utilisés en toute sécurité dans Hyper-V - vous tuez deux oiseaux avec une pierre à la fois. N'oubliez pas de faire une copie du référentiel BCD à l'avance via la commande
bcdedit / export e: \ bcd_backup.bcd .
Je ne voulais pas configurer AD pour la distribution des mises à jour, j'ai donc simplement enregistré le chemin d'accès au serveur WSUS dans les stratégies de groupe:

Assurez-vous de faire attention au port, en raison d'une faute de frappe (8350 au lieu de 8530), je n'ai pas pu recevoir de mises à jour sur les machines clientes, bien que tout ait été fait correctement. En outre, les noms des éléments des stratégies de groupe sous Windows 7 et Windows 8 sont différents.
Pour recevoir le rapport à l'aide de WSUS, vous devez en outre installer le package - le système vous en informera.
Et maintenant un petit code Comme il n'y a pas d'Internet, la situation des mises à jour se présente comme dans la capture d'écran ci-dessous:

Le comportement est similaire à WUApi - si les mises à jour ne les ont pas traversées, alors ils ne le savent pas. Par conséquent, cette méthode ne fonctionne plus.
Wmi
Windows Management Instrumentation (
WMI ) dans la traduction littérale est une boîte à outils de gestion Windows.
WMI est une norme mise en œuvre par Microsoft pour gérer une entreprise
sur Internet pour l'administration et la surveillance centralisées de diverses parties d'une infrastructure informatique exécutant une plate-forme Windows. WMI est un système ouvert et unifié d'interfaces d'accès à tous les paramètres du système d'exploitation, des appareils et des applications qui y fonctionnent.
Cette méthode vous permet de recevoir des données à la fois de la machine locale et à distance au sein du réseau local. Pour accéder aux objets WMI, un langage de requête WMI (WQL) spécifique est utilisé, qui est l'une des variétés de SQL. Nous recevrons la liste via la classe WMI
win32_quickfixengineering .
Exemple d'implémentation using System.Management; public static List<string> GetWMIlist(params string[] list) { List<string> result = new List<string>(200);
Quantitativement, tout coïncide (même après les mises à jour), il a donc été décidé d'utiliser cette méthode. Pour la création par programme de requêtes WMI, je vous conseille d'utiliser l'utilitaire suivant -
WMI Delphi Code Creator . Grâce à elle, j'ai regardé mon code un peu différemment et j'ai décidé d'utiliser un blanc de ce programme.
XML
Les données obtenues par la méthode WMI ne m'ont pas arrêté et j'ai opté pour le «reverse engineering de surface». Nous utiliserons l'utilitaire
Process Monitor de la collection de logiciels
Sysinternals Suite pour identifier les fichiers et les branches de registre utilisés lors de l'appel des commandes de la console répertoriées ci-dessus et de l'accès à l'élément «Mises à jour installées» via le panneau de configuration.
Mon attention a été attirée sur le fichier wuindex.xml situé dans le dossier C: \ Windows \ servicing \ Packages \. Pour l'analyser, le programme suivant a été écrit:
Exemple d'application console using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Xml; using System.Text.RegularExpressions; using System.IO; namespace XMLviewer { class Program { static void Main(string[] args) { string writePath = AppDomain.CurrentDomain.BaseDirectory + "XML " + Environment.MachineName + ".txt"; if (!File.Exists(writePath)) { Console.WriteLine(" txt "); } else { Console.WriteLine(" XML .txt , "); File.Delete(writePath); }
Malheureusement, ce fichier ne se trouve pas sur tous les systèmes et le principe de sa génération et de sa mise à jour est resté un mystère pour moi. Par conséquent, encore une fois, cette méthode ne nous convient pas.
Cbs
Nous arrivons ici à ce que toutes ces méthodes sont associées. Poursuivant l'analyse des journaux de Process Monitor, j'ai identifié les dossiers et fichiers suivants.
Le fichier DataStore.edb situé dans le dossier
C: \ Windows \ SoftwareDistribution \ DataStore . Il s'agit d'une base de données qui contient l'historique de toutes les mises à jour de la version installée de Windows, y compris celles qui sont uniquement mises en file d'attente.
Le programme ESEDatabaseView a été utilisé pour analyser le fichier DataStore.edb. Il existe une table tbUpdates dans la base de données, dont le contenu est difficile à interpréter.

Après avoir attiré mon attention sur le processus
TiWorker.exe , qui était appelé chaque fois que
j'ouvrais un élément dans le Panneau de configuration. Il a «parcouru» de nombreux dossiers, dont l'un m'a conduit sur la bonne voie.
C: \ Windows \ SoftwareDistribution est un dossier utilisé par Windows Update pour télécharger les mises à jour sur un ordinateur et les installer, et il stocke également des informations sur toutes les mises à jour précédemment installées.
Dossier WinSxS situé dans
C: \ Windows \ winsxs . Il s'agit du dossier de service du système d'exploitation Windows utilisé pour stocker les versions précédemment installées des composants du système. En raison de sa présence, il est possible de revenir à une ancienne version de la mise à jour si nécessaire.
C: \ Windows \ servicing - le composant principal de tout le système, dont le nom est
Component-Based Servicing (CBS) .
CBS est un service basé sur des composants qui fait partie de Windows et est intégré au service Windows Update. Contrairement au
service de maintenance basée sur les
fichiers (FBS) (pour les systèmes d'exploitation antérieurs à Windows Vista), dans lequel les fichiers étaient mis à jour directement dans les répertoires système, CBS a introduit toute une hiérarchie de répertoires et toute une famille (pile) de modules / bibliothèques de services.
CbsApi.dll est la principale bibliothèque de support technologique CBS. Il n'a pas de méthodes ouvertes, je ne pouvais donc pas l'utiliser directement. Microsoft utilise TrustedInstaller.exe et TiWorker.exe pour accéder aux méthodes de cette bibliothèque et déjà via ces processus affiche les données dont nous avons besoin. Les enregistrements sont conservés dans
C: \ Windows \ Logs \ CBS \ CBS.log .
Au moment de la création du prototype du programme (vous pouvez voir mai 2019 dans les captures d'écran), il n'y avait pas d'informations en russe sur CBS, mais à la fin août, il y avait un très bon article de blog -
http://datadump.ru/component-based-servicing . Un article très intéressant qui a confirmé mon expérience et rassemblé les informations nécessaires. Et plus sur le sujet:
http://www.outsidethebox.ms/17988/Conclusion
Microsoft a trop compliqué la tâche triviale d'obtenir une liste de mises à jour et a rendu ce processus pas tout à fait évident. Tout cela est fait pour la sécurité, mais pas pour la facilité d'utilisation. Je suis d'accord avec l'auteur de l'
article - la prévisibilité et la transparence ont commencé à être absentes lors de la réception des mises à jour.
À la suite de l'étude, le
programme suivant
a été écrit, dont une démonstration peut être vue dans cette vidéo:
Le projet d'ajouter:
- comparer la liste des mises à jour nécessaires avec celle reçue;
- envoyer le résultat via SNMP / OPC (si quelqu'un a de l'expérience, partagez les commentaires);
- organiser l'installation des mises à jour «hors ligne» manquantes à partir du dossier spécifié.
Si vous connaissez plus de méthodes pour obtenir une liste non seulement des mises à jour, mais aussi des composants supplémentaires (Adobe Flash, Acrobat Reader, etc.) ou si vous avez d'autres suggestions intéressantes, écrivez à ce sujet dans les commentaires ou dans les messages privés - je serai heureux de recevoir des commentaires . Et participez à l'enquête pour cet article - je saurai donc si mon expérience avec le public Habrahabr sera intéressante.