繁体   English   中英

有没有办法使用 C# 访问上次安装 Windows 更新的日期?

[英]Is there a way to access the date of the last installed Windows update using C#?

我正在努力将 powershell 脚本的一部分改编为 WPF C# windows 服务,但我无法找到一种方法来获取最后安装的 windows 更新,就像下面的脚本一样。 我需要一种方法来检查工作站是否在过去 30 天内安装了 Windows 更新,如果它通过了审核,如果不是,它没有通过审核。

$today = Get-Date   
$session = (New-Object -ComObject 'Microsoft.Update.Session')
$lastUpdate = ($session.QueryHistory("",0,100) | Where-Object 
{$_.ResultCode -eq 2}).Date | Sort-Object -descending
$compInfo = Get-ComputerInfo | select WindowsProductName, WindowsVersion
$OSversion = ($compInfo.WindowsProductName + " " + $compInfo.WindowsVersion).replace("Windows ","")

if (!$lastUpdate) {
    $never = $true
    $lastUpdate = Get-Date -Year 0001 -Month 01 -Day 01 -Hour 00 -Minute 00 -Second 00
} else {
    # Convert from UTC to timezone
    $timediff = [int]((Get-Timezone | select BaseUtcOffset | Out-String -Stream)[3][2].ToString())
    $lastUpdate = $lastUpdate[0].AddHours(-$timediff)
}

# Audit result
if ($never -or [datetime]$lastUpdate -le ($today.AddDays(-30))) {
    # Audit fail
    $pass = $false
    if ($never) {
        $lastUpdate = "Never"
    } else {
        $lastUpdate = [string]$lastUpdate
    }
} else {
    # Audit pass
}

我一直在阅读有关 WUApi 的信息,但在尝试使用 IUpdateSearcher 类时无法获得以下代码的任何变体以不产生错误。 我已经尝试过不同的命名空间,但仍然没有任何运气。

using WUApiLib;

UpdateSessionClass uSession = new UpdateSessionClass();
IUpdateSearcher uSearcher = uSession.CreateUpdateSearcher();
ISearchResult uResult = uSearcher.Search("IsInstalled=0 and Type='Software'");

似乎我无法准确复制 powershell 版本,但是根据我对 WUAPI 的研究,我可以检查计算机是否有任何尚未安装的更新,如果有则分配一个通行证没有更新,如果有则失败。

正如这里所解释的,您可以编译一个总结更新的文件。

默认情况下,它会写入您的桌面:

"%USERPROFILE%\Desktop\WindowsUpdate.log"

此操作可以作为脚本或程序的子进程启动。 它不需要管理权限。

然后,您可以将文件读取到如下内容:

2022.07.06 16:56:05.5197996 3936  8528  UDP               Title = Security Intelligence-Update f??r Microsoft Defender Antivirus - KB2267602 (Version 1.369.880.0)
2022.07.06 16:56:05.5198024 3936  8528  UDP               UpdateId = B701392C-6DF8-4D94-A07F-35D06C5014E7.200

Title行按时间顺序包含更新的日期/时间和KB数。

在评论中,您提到了这些(编译时)错误:

找不到类型或命名空间名称“UpdateSessionClass”(您是否缺少 using 指令或程序集引用?)
找不到类型或命名空间名称“IUpdateSearcher”(您是否缺少 using 指令或程序集引用?)

显然,您对 WUApi.dll 的引用有问题。 这应该有效:

  1. 在解决方案资源管理器中,在项目名称正下方,右键单击依赖项。 出现一个上下文菜单。
  2. 从上下文菜单中,选择“添加 COM 引用...” 出现“引用管理器”对话框。
  3. 在对话框中的 COM 选项卡上,向下滚动并选中“WUAPI 2.0 类型库”。 单击确定。

现在您可以查询更新历史记录,就像您在 PowerShell 脚本中所做的一样。

using WUApiLib;

IUpdateSession3 session = new UpdateSession();
IUpdateHistoryEntryCollection history = session.QueryHistory("", 0, 1);
if (history.Count > 0)
{
    Console.WriteLine($"Latest Windows update was on {history[0].Date}.");
}
else
{
    Console.WriteLine("Not a single Windows update found.");
}

请注意,我自己并没有对历史进行排序。 文档(强调我的):

[out] retval指向IUpdateHistoryEntryCollection接口的指针,该接口包含计算机上按时间降序排列的匹配事件记录。

换句话说,第一行是最新的更新。 因此调用IUpdateSession3::QueryHistory时的这些参数:

  • "" : 没有搜索条件,随便找我
  • 0 : 从顶部开始
  • 1 :给我(最多)一行

请记住,历史记录可能会产生之后已回滚的更新。 我不知道如何解决这个问题。 但我认为您的 PowerShell 脚本也有同样的问题。

感谢这篇文章中有用的代码示例: https ://stackoverflow.com/a/815525/2485966

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM