¿Alguna vez te has preguntado por qué se genera una lista de actualizaciones de Windows instaladas? ¿Y a través de qué API conseguirlo? Intentaré dar respuestas a estas y otras preguntas emergentes en mi pequeño estudio.

Antecedentes o cómo comenzó todo.
Cada año se celebra una conferencia de jóvenes especialistas
en nuestra empresa , donde cada participante puede resolver el problema de un departamento (se propone una lista de temas por adelantado). Y el departamento de SPAS (soporte de software y hardware) tenía la siguiente tarea, que me interesó, además de que me permitió volver a la programación nuevamente (desafortunadamente, en este momento trabajo en esta empresa como un simple operador de NPPS).
Anteriormente, por cada "TO" con la ayuda de WSUS, todas las actualizaciones lanzadas se extraían y distribuían a todas las máquinas. TSB (boletines de servicio técnico) también aparecían periódicamente, lo que indicaba que era necesario instalar las actualizaciones necesarias en forma de paquetes aislados. Como resultado, acumulamos actualizaciones que no se pueden rastrear en WSUS, pero solo se pueden ver a través del panel de control en la sección "Actualizaciones instaladas".

Hay situaciones en las que la estación de trabajo o el servidor se "cuelga" y debe restaurarlo a partir de una imagen creada hace algún tiempo. Al recuperarse de una imagen, existe la posibilidad de que perdamos las actualizaciones que necesitamos (que vienen en forma de paquetes aislados) que se instalaron antes de que la máquina se bloqueara. Explicado lo más detallado posible, porque las aclaraciones ya serán un secreto comercial.
Es por eso que surgió la idea de crear un programa que pudiera extraer esta lista de actualizaciones (preferiblemente de
forma remota a través de la red local), escribir en un archivo / base de datos, comparar la lista actual con una plantilla determinada y enviar un mensaje al sistema SCADA a través de uno de los protocolos: SNMP, OPC.
Como habrás adivinado por el título del artículo, ya tenía una tarea difícil para elegir el método de recuperación de la lista. Como de costumbre, decidí buscar el correcto en el motor de búsqueda, hice preguntas sobre recursos especializados (
uno ,
dos , por alguna razón, a stackoverflow en inglés no me gustó mi pregunta y tuve que eliminarlo), pero todas las respuestas no dieron el resultado deseado. Por lo tanto, tuve que resolverlo yo mismo, lo que se discutirá más adelante.
Comandos de la consola
Comencemos con uno simple y aprovechemos lo que Windows nos ofrece sin usar herramientas de terceros. Esto se puede hacer usando los siguientes comandos:
- wmic qfe list
- systeminfo
- dism / online / get-packages
- a través de PowerShell:
- Obtener revisión
- Get-SilWindowsUpdate (solo disponible en ediciones de servidor)
- Get-WmiObject -Class win32_quickfixengineering - a través del acceso a la clase WMI win32_quickfixengineering (sobre WMI un poco más tarde)
Puede obtener la lista a través de la interfaz gráfica a través del elemento estándar del Panel de control "Agregar o quitar programas", pero no podemos copiar nada desde allí. Cada herramienta del panel de control está representada por un archivo .cpl en la carpeta Windows \ System. Los archivos .pl en la carpeta del sistema de Windows se descargan automáticamente cuando se inicia el panel de control. El archivo Appwiz.cpl es responsable del elemento del programa. Su análisis no condujo a nada.
La salida del comando de la consola se puede redirigir a un archivo y luego se puede analizar, pero esto es incorrecto, más una llamada al programa (de acuerdo con las reglas de SB, no funcionará) y no se trata de recibir la lista de forma remota. Por lo tanto, le sugiero que simplemente llame a los comandos, compare el número de actualizaciones en cada lista, con la lista a través del Panel de control y continúe nuestra investigación.
Formalmente, todos los métodos para obtener la lista de actualizaciones se pueden dividir en dos grupos: local y de red.

Todos los métodos se probaron en imágenes limpias del sistema (Windows 7, 8, Server 2012 R2) con actualizaciones integradas, después de cada actualización a través del Centro de actualizaciones de los servidores oficiales de Microsoft se realizó una verificación adicional. Detengámonos en cada uno de ellos con más detalle.
WUA
WUApi (API del Agente de Windows Update): uso de la API del Agente de Windows Update. La opción más obvia, cuyo nombre habla por sí mismo. Usaremos la biblioteca Wuapi.dll para esto.
Nota: en lo sucesivo, para mi comodidad, incrustaré todos los resultados en la Lista. Esto puede no ser racional, pero me pareció una buena idea.
Ejemplo de implementaciónusing WUApiLib; public static List<string> listUpdateHistory() {
Hay una segunda variación de este método:
Sesión de actualización : recibir información conectándose a la sesión de actualización del Agente de Windows Update (en este caso, no trabajamos directamente con la biblioteca).
Ejemplo de implementación public static List<string> Sessionlist(string pc) { List<string> result = new List<string>(50);
Microsoft sugiere el
uso remoto
de la API .
Las principales desventajas de estos dos métodos son que no le permiten encontrar correcciones de KB que no se distribuyen a través de Windows Update. Solo puede ver lo que pasó por el agente de actualización en sí, es decir, esta opción no nos conviene.
DISM
Deployment Image Servicing and Management es una herramienta de línea de comandos que se puede utilizar para dar servicio a una imagen de Windows o para preparar una imagen de un entorno de preinstalación de Windows (Windows PE). Es un reemplazo para Package Manager (Pkgmgr.exe), PEimg e Intlcfg.
Esta utilidad se utiliza para integrar actualizaciones, paquetes de servicio en la imagen del sistema. Las actualizaciones de Windows son módulos separados que se pueden presentar de varias maneras:
- Archivos .cab (gabinete) - archivos. Diseñado para distribución e instalación utilizando módulos de Windows Update en modo automatizado;
- Archivos .msu (paquete independiente de Microsoft Update): archivos ejecutables. Diseñado para su distribución e instalación por los propios usuarios en modo manual a través del catálogo de actualizaciones de Microsoft. De hecho, son un conjunto empaquetado que consta de archivos .cab-, .xml, .txt.
El
comando anteriormente mencionado
dism / online / get-packages muestra información básica sobre todos los paquetes en la imagen de wim / sistema actual. Microsoft se ha ocupado de nosotros y proporciona
paquetes NuGet para un uso conveniente de la API.
Ejemplo de implementación 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;
El número de actualizaciones coincidió con el número de la lista del Panel de control hasta la primera actualización a través del centro de control; después de eso, el número de actualizaciones disminuyó (fueron 214, se convirtió en 209), aunque lógicamente deberían haber aumentado. Ejemplos de salida
Antes de actualizar ,
Después de actualizar .
Cuál es la razón de esto, solo puedo especular: quizás algunas actualizaciones reemplazaron a las anteriores, por lo tanto, el número se volvió menos.
Un poco más tarde, encontré una utilidad del
DISM ++ chino, que no se basa en la API DISM o la API DISM Core, pero las bibliotecas que tiene no tienen los métodos que necesito abrir, por lo que abandoné esta idea y continué buscando más.
WSUS
Windows Server Update Services (
WSUS ) es un servidor para actualizar sistemas operativos y productos de Microsoft. El servidor de actualización se sincroniza con el sitio web de Microsoft, descargando actualizaciones que pueden distribuirse dentro de la LAN corporativa. Una vez más, una herramienta especial diseñada para trabajar con actualizaciones.
Distribuido solo en las ediciones del servidor de Windows, por lo que se implementó el siguiente soporte:
- el sistema principal es Windows Server 2016;
- y a través del sistema de virtualización Hyper-V, se implementaron dos sistemas operativos cliente:
Todos los sistemas están conectados a una única red de área local virtual, pero
sin acceso a Internet .
Algunos consejosPara no asignar una partición de disco duro para el nuevo sistema, uso
WinNTSetup e instalo el sistema en discos VHD: el cargador de arranque, que comienza con Windows 7 (ediciones Professional / Ultimate), se adapta perfectamente al arranque desde una imagen de disco. Los discos así obtenidos se pueden usar de forma segura en Hyper-V: matas dos pájaros de un tiro a la vez. Recuerde hacer una copia del repositorio BCD por adelantado a través del
comando bcdedit / export e: \ bcd_backup.bcd .
No quería configurar AD para la distribución de actualizaciones, por lo tanto, simplemente registré la ruta al servidor WSUS en las políticas de grupo:

Asegúrese de prestar atención al puerto, debido a un error tipográfico (8350 en lugar de 8530) no pude recibir actualizaciones en las máquinas cliente, aunque todo se hizo correctamente. Además, los nombres de los elementos en las políticas de grupo en Windows 7 y Windows 8 son diferentes.
Para recibir el informe utilizando WSUS, debe instalar adicionalmente el paquete; el sistema se lo notificará.
Y ahora un pequeño código Como no hay Internet, la situación con las actualizaciones aparece como en la siguiente captura de pantalla:

El comportamiento es similar a WUApi: si las actualizaciones no han pasado por ellos, entonces no lo saben. Por lo tanto, este método no funciona nuevamente.
Wmi
El Instrumental de administración de Windows (
WMI ) en traducción literal es un kit de herramientas de administración de Windows.
WMI es un estándar implementado por Microsoft para administrar una empresa a
través de Internet para la administración centralizada y el monitoreo de varias partes de una infraestructura informática que ejecuta una plataforma Windows. WMI es un sistema abierto unificado de interfaces de acceso a cualquier parámetro del sistema operativo, dispositivos y aplicaciones que operan en él.
Este método le permite recibir datos tanto de la máquina local como de forma remota dentro de la red local. Para acceder a los objetos WMI, se utiliza un lenguaje de consulta WMI (WQL) específico, que es una de las variedades de SQL.
Recibiremos la lista a través de la clase WMI
win32_quickfixengineering .
Ejemplo de implementación using System.Management; public static List<string> GetWMIlist(params string[] list) { List<string> result = new List<string>(200);
Cuantitativamente, todo coincide (incluso después de las actualizaciones), por lo que se decidió utilizar este método. Para la creación programática de solicitudes WMI, le aconsejo que use la siguiente utilidad:
WMI Delphi Code Creator . Gracias a ella, miré mi código un poco diferente y decidí usar un espacio en blanco de este programa.
XML
Los datos obtenidos por el método WMI no me detuvieron, y decidí "ingeniería inversa de superficie". Utilizaremos la utilidad
Process Monitor de la colección de software
Sysinternals Suite para identificar los archivos y las ramas de registro que se usan al llamar a los comandos de la consola enumerados anteriormente y acceder al elemento "Actualizaciones instaladas" a través del Panel de control.
Me llamó la atención el archivo wuindex.xml ubicado en la carpeta C: \ Windows \ servicing \ Packages \. Para analizarlo, se escribió el siguiente programa:
Ejemplo de aplicación de consola 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); }
Desafortunadamente, este archivo no se encuentra en todos los sistemas y el principio de su generación y actualización ha sido un misterio para mí. Por lo tanto, nuevamente este método no nos conviene.
Cbs
Aquí llegamos a lo que todos estos métodos están asociados. Continuando con el análisis de los registros de Process Monitor, identifiqué las siguientes carpetas y archivos.
El archivo DataStore.edb ubicado en la
carpeta C: \ Windows \ SoftwareDistribution \ DataStore . Esta es una base de datos que contiene el historial de todas las actualizaciones de la versión instalada de Windows, incluidas las que solo están en cola.
El programa ESEDatabaseView se utilizó para analizar el archivo DataStore.edb. Hay una tabla tbUpdates en la base de datos, cuyo contenido es difícil de interpretar.

Después de llamar mi atención sobre el proceso
TiWorker.exe , que se llamaba cada vez que abría un elemento en el Panel de control. Él "caminó" a través de muchas carpetas, una de las cuales me llevó por el camino correcto.
C: \ Windows \ SoftwareDistribution es una carpeta utilizada por Windows Update para descargar actualizaciones a una computadora e instalarlas, y también almacena información sobre todas las actualizaciones instaladas previamente.
Carpeta WinSxS ubicada en
C: \ Windows \ winsxs . Esta es la carpeta de servicio del sistema operativo Windows utilizada para almacenar versiones instaladas previamente de componentes del sistema. Debido a su presencia, es posible volver a una versión anterior de la actualización si es necesario.
C: \ Windows \ servicing : el componente principal de todo el sistema, cuyo nombre es
Servicio basado en componentes (CBS) .
CBS es un servicio basado en componentes que forma parte de Windows y está integrado con el servicio de actualización de Windows. A diferencia
del servicio de mantenimiento basado en
archivos (FBS) (para sistemas operativos anteriores a Windows Vista), en el que los archivos se actualizaban directamente en los directorios del sistema, CBS introdujo una jerarquía completa de directorios y una familia completa (pila) de módulos / bibliotecas de servicios.
CbsApi.dll es la biblioteca principal de soporte de tecnología CBS. No tiene métodos abiertos, por lo que no podría usarlo directamente. Microsoft usa TrustedInstaller.exe y TiWorker.exe para acceder a los métodos de esta biblioteca y ya a través de estos procesos muestra los datos que necesitamos. Los registros se mantienen en
C: \ Windows \ Logs \ CBS \ CBS.log .
En el momento de la creación del prototipo del programa (puede ver mayo de 2019 en las capturas de pantalla), no había información en ruso sobre CBS, pero a fines de agosto había un muy buen artículo de blog:
http://datadump.ru/component-based-servicing . Un artículo muy interesante que confirmó mi experiencia y recopiló la información necesaria. Y más sobre el tema:
http://www.outsidethebox.ms/17988/Conclusión
Microsoft ha complicado demasiado la tarea trivial de obtener una lista de actualizaciones y ha hecho que este proceso no sea del todo obvio. Todo esto se hace por seguridad, pero no por facilidad de uso. Estoy de acuerdo con el autor del
artículo : la previsibilidad y la transparencia comenzaron a faltar al recibir actualizaciones.
Como resultado del estudio, se escribió el siguiente
programa , cuya demostración se puede ver en este video:
Los planes para agregar:
- comparar la lista de actualizaciones necesarias con la recibida;
- envíe el resultado a través de SNMP / OPC (si alguien tiene experiencia, comparta los comentarios);
- organizar la instalación de las actualizaciones "fuera de línea" que faltan de la carpeta especificada.
Si conoce más métodos para obtener una lista no solo de actualizaciones, sino también componentes adicionales (Adobe Flash, Acrobat Reader, etc.) o si tiene otras sugerencias interesantes, escríbalas en los comentarios o en mensajes privados. Estaré encantado de recibir cualquier comentario . Y participe en la encuesta para este artículo, así sabré si mi experiencia con la audiencia de Habrahabr será interesante.