您是否想知道为什么会生成已安装的Windows更新列表? 并通过哪个API获取呢? 我将在我的小型研究中尝试回答这些问题以及其他新出现的问题。

背景或一切的开始。
每年
我们公司都会召开一次年轻专家会议,每个参与者都可以解决一个部门的问题(预先提出主题列表)。 SPAS的部门(软件和硬件的维护)具有以下任务,这使我感兴趣,此外,它使再次返回编程成为可能(不幸的是,此刻,我在这家公司工作时只是一个NPPS的简单运营商)。
以前,在WSUS的帮助下,对于每个“ TO”,所有发布的更新都被提取并分发到所有计算机。 TSB(技术服务公告)也定期出现,这表明需要以隔离软件包的形式安装必要的更新。 结果,我们累积了无法在WSUS中跟踪的更新,而这些更新只能通过“已安装的更新”部分中的控制面板看到。

在某些情况下,工作站或服务器“崩溃”,您必须从前一段时间创建的映像中还原它。 从映像恢复时,我们可能会丢失在计算机崩溃之前安装的所需更新(以隔离软件包的形式出现)。 尽可能详细地解释,因为澄清已经是商业秘密。
这就是为什么这个想法出现的原因是创建一个程序,该程序可以提取此更新列表(最好是
通过本地网络
远程 ),写入文件/数据库,将当前列表与特定模板进行比较并通过SNMP,OPC等协议之一将消息发送到SCADA系统。
正如您可能从文章标题中猜到的那样,选择列表检索方法已经是一项艰巨的任务。 像往常一样,我决定在搜索引擎中搜索正确的一个,在专用资源上提出问题(
一个 ,
两个 ,出于某种原因,英语的stackoverflow不喜欢我的问题,因此必须删除),但是所有答案都没有得到理想的结果。 因此,我必须自己弄清楚,稍后将进行讨论。
控制台命令
让我们从一个简单的例子开始,充分利用Windows提供的功能,而无需使用第三方工具。 可以使用以下命令完成此操作:
- WMIC QFE清单
- 系统信息
- Dism /在线/获取软件包
- 通过PowerShell:
- 获取修补程序
- Get-SilWindowsUpdate (仅在服务器版本中可用)
- Get-WmiObject-类win32_quickfixengineering-通过访问WMI类win32_quickfixengineering(稍后再介绍WMI)
您可以通过控制面板“添加/删除程序”的标准项通过图形界面获得列表,但我们无法从此处复制任何内容。 每个控制面板工具由Windows \ System文件夹中的.cpl文件表示。 控制面板启动时,Windows系统文件夹中的.Cpl文件将自动下载。 Appwiz.cpl文件负责“程序”项。 他的分析没有得出任何结果。
可以将console命令的输出重定向到一个文件,然后可以对其进行解析,但这是错误的,再加上一个程序调用(根据安全理事会的规定将不起作用),而且毫无疑问可以远程接收该列表。 因此,我建议您只需调用命令,通过控制面板将每个列表中的更新数量与列表进行比较,然后继续我们的调查。
正式地,获取更新列表的所有方法可以分为两组:本地和网络。

所有方法都在带有集成更新的干净系统映像(Windows 7、8,Server 2012 R2)上进行了测试,在从官方Microsoft服务器通过更新中心进行的每次更新之后,都进行了附加检查。 让我们更详细地介绍它们。
用水户协会
WUApi (Windows Update代理API)-使用Windows Update代理API。 最明显的选择,其名称说明一切。 我们将为此使用Wuapi.dll库。
注意:以下,为方便起见,我将所有结果嵌入到列表中。 这可能不是合理的,但是对我而言,这似乎是个好主意。
实施实例using WUApiLib; public static List<string> listUpdateHistory() {
此方法的第二种变化是:
更新会话 -通过连接到Windows Update代理更新会话来接收信息(在这种情况下,我们不直接与该库一起使用)。
实施实例 public static List<string> Sessionlist(string pc) { List<string> result = new List<string>(50);
微软建议远程
使用该API 。
这两种方法的主要缺点是它们不允许查找未通过Windows Update分发的KB修补程序。 您只能看到更新代理本身经历了什么,也就是说,此选项不适合我们。
DISM
部署映像服务和管理是一个命令行工具,可用于服务Windows映像或准备Windows预安装环境(Windows PE)的映像。 它替代了程序包管理器(Pkgmgr.exe),PEimg和Intlcfg。
该实用程序用于将更新,Service Pack集成到系统映像中。 Windows更新是单独的模块,可以通过几种方式呈现:
- .cab文件(内阁)-存档。 设计用于以自动模式使用Windows Update模块进行分发和安装;
- .msu文件(Microsoft Update独立软件包)-可执行文件。 专为用户自己通过Microsoft更新目录以手动模式分发和安装而设计。 实际上,它们是由.cab-、. xml和.txt文件组成的打包集。
前面提到的
dism / online / get-packages命令显示有关wim映像/当前系统中所有软件包的基本信息。 Microsoft已经照顾了我们,并提供了
NuGet软件包以方便使用API。
实施实例 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;
更新数量与“控制面板”列表中的数量一致,直到通过控制中心进行的第一次更新-之后,更新数量变少了(它是214,变成了209),尽管从逻辑上讲应该增加。 输出示例
更新前,更新 后 。
这是什么原因,我只能推测-也许某些更新替代了以前的更新,因此数量减少了。
过了一会儿,我遇到了中文
DISM ++的实用程序,该实用程序不基于DISM API或DISM Core API,但是它的库没有我需要打开的方法,因此我放弃了这个想法并继续进行进一步的搜索。
华硕
Windows Server Update Services(
WSUS )是用于更新操作系统和Microsoft产品的服务器。 更新服务器与Microsoft网站同步,下载可以在公司LAN内分发的更新。 同样,一个专门用于更新的专用工具。
仅在Windows的服务器版本上分发,因此部署了以下支架:
- 主系统是Windows Server 2016;
- 通过Hyper-V虚拟化系统,部署了两个客户端操作系统:
所有系统都连接到单个虚拟局域网,但
不能访问Internet 。
一些技巧为了不为新系统分配硬盘分区,我使用
WinNTSetup并将系统安装在VHD磁盘中-从Windows 7(专业版/旗舰版)开始的引导加载程序在从磁盘映像引导方面做得很好。 这样获得的磁盘可以在Hyper-V中安全使用-您一次用一块石头杀死了两只鸟。 请记住,只需通过
bcdedit / export e:\ bcd_backup.bcd命令预先复制BCD存储库。
我不想配置用于分发更新的AD,因此我只是在组策略中注册了WSUS服务器的路径:

由于输入错误(8350而不是8530),请务必注意端口,尽管一切都已正确完成,但我无法在客户端计算机上收到更新。 此外,Windows 7和Windows 8上的组策略中项目的名称也不同。
要使用WSUS接收报告,您必须另外安装软件包-系统将通知您。
由于没有互联网,因此出现更新情况,如以下屏幕截图所示:

行为与WUApi类似-如果更新未通过更新,则他们不知道。 因此,此方法不再起作用。
Wmi
直译的Windows Management Instrumentation(
WMI )是Windows管理工具箱。
WMI是Microsoft实施的标准,用于
通过Internet管理企业
,以集中管理和监视运行Windows平台的计算机基础结构的各个部分。 WMI是访问接口的开放统一系统,可以访问其中运行的操作系统,设备和应用程序的任何参数。
此方法使您既可以从本地计算机接收数据,也可以从本地网络远程接收数据。 要访问WMI对象,使用特定的WMI查询语言(WQL),它是SQL的一种。 我们将通过WMI类
win32_quickfixengineering接收列表。
实施实例 using System.Management; public static List<string> GetWMIlist(params string[] list) { List<string> result = new List<string>(200);
从数量上讲,所有内容都是重合的(即使在更新后也是如此),因此决定使用此方法。 对于以编程方式创建WMI请求,我建议您使用以下实用程序
-WMI Delphi Code Creator 。 多亏了她,我对我的代码有所不同,并决定使用此程序中的空白。
XML格式
通过WMI方法获得的数据并没有阻止我,因此我决定进行“表面逆向工程”。 我们将使用
Sysinternals Suite软件集中的
Process Monitor实用程序来识别在调用上面列出的控制台命令并通过“控制面板”访问“已安装的更新”项时使用的文件和注册表分支。
我的注意力吸引到位于C:\ Windows \ serviceic \ Packages \文件夹中的wuindex.xml文件。 为了对其进行分析,编写了以下程序:
控制台应用程序示例 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); }
不幸的是,该文件并非在所有系统上都可以找到,其生成和更新的原理仍然是我的一个谜。 因此,这种方法也不适合我们。
立方英尺
在这里,我们来探讨所有这些方法的关联。 继续分析Process Monitor日志,我确定了以下文件夹和文件。
位于
C:\ Windows \ SoftwareDistribution \ DataStore文件夹中的DataStore.edb文件 。 这是一个数据库,其中包含Windows安装版本的所有更新的历史记录,包括仅排队的更新。
ESEDatabaseView程序用于分析DataStore.edb文件。 数据库中有一个tbUpdates表,其内容难以解释。

引起我注意
TiWorker.exe进程后,每次我在“控制面板”中打开一个项目时都会调用该进程。 他“浏览”了许多文件夹,其中之一使我走上了正轨。
C:\ Windows \ SoftwareDistribution是Windows Update用于将更新下载到计算机并安装它们的文件夹,它还存储有关所有以前安装的更新的信息。
位于
C:\ Windows \ winsxs的 WinSxS文件夹。 这是Windows操作系统的服务文件夹,用于存储以前安装的系统组件版本。 由于存在更新,因此如有必要,可以回滚到更新的旧版本。
C:\ Windows \ serviceic-整个系统的主要组件,名称为
基于组件的服务(CBS) 。
CBS是Windows的一部分,是基于组件的服务,并且与Windows Update服务集成在一起。 与
基于文件的服务(FBS)服务 (适用于Windows Vista之前的操作系统)不同,在文件服务中直接在系统目录中更新文件,而CBS则引入了整个目录层次结构以及模块/服务库的整个系列(堆栈)。
CbsApi.dll是主要的CBS技术支持库。 它没有开放的方法,所以我不能直接使用它。 Microsoft使用TrustedInstaller.exe和TiWorker.exe访问该库的方法,并通过这些过程显示我们需要的数据。 记录保存在
C:\ Windows \ Logs \ CBS \ CBS.log中 。
在创建该程序的原型时(您可以在屏幕截图中看到2019年5月),没有关于CBS的俄语信息,但是在8月底,有一个非常不错的博客文章
-http://datadump.ru/component-based-servicing 。 一篇非常有趣的文章证实了我的经验并收集了必要的信息。 有关该主题的更多信息:
http :
//www.outsidethebox.ms/17988/结论
Microsoft太复杂了获取更新列表的琐碎任务,并使此过程不十分明显。 所有这些都是为了安全起见,而不是为了易于使用。 我同意
本文的作者-在接收更新时开始缺乏可预测性和透明度。
作为研究的结果,编写了以下
程序 ,可以在此视频中看到其演示:
计划添加:
- 将必要更新列表与接收到的更新进行比较;
- 通过SNMP / OPC发送结果(如果有经验,请在评论中分享);
- 从指定的文件夹组织丢失的“脱机”更新的安装。
如果您知道更多不仅可以获取更新列表,而且还可以获取其他组件(Adobe Flash,Acrobat Reader等)列表的方法,或者您还有其他有趣的建议,请在评论或私人消息中写上它-我将很高兴收到任何反馈。 并参与本文的调查-因此,我将知道我对Habrahabr受众的经历是否会很有趣。