在 SCCM2012 中对应用程序评估进行故障排除

在 SCCM2012 中对应用程序评估进行故障排除

我遇到了一个有趣的问题,一些应用程序在 SCCM 2012 中无法正确评估。我拥有的示例软件是 Adob​​e reader 11。当我通过软件中心使用 MSI 部署进行安装时,一切都运行良好。当有人访问 Adob​​e 网站并下载可执行安装程序并运行它时,就会出现问题。现在软件中心检测到该软件已卸载,并将其列为可用标题。

我正在使用“Windows 安装程序”检测方法并寻找此 GUID“{AC76BA86-7AD7-1033-7B44-AB0000000001}”。当我查看 AppDiscovery.log 时,我得到的只是“+++ 应用程序未发现。”消息。

问题是:我可以在哪里看到检测方法正在查询什么以及它返回什么?

附加问题:执行“Windows 安装程序”检测时,系统在哪里寻找该 GUID?

提前致谢

答案1

好吧,这将是一篇很长的文章,但是里面有很多好东西。

首先,已安装软件的 GUID 位于以下位置...

对于 32 位 Windows 以及 64 位 Windows 上的 64 位软件:
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall

对于 64 位 Windows 上的 32 位软件:
HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall

您遇到的问题是 GUID 字符串不正确。您从 Adob​​e 下载的 MSI 是美国英语版本,因此 GUID 字符串的第三部分是 1033(1033 是美国键盘的 ANSI 代码页)。

但是,EXE 安装程序是 MUI 版本,其 GUID 为 {AC76BA86-7AD7-FFFF-7B44-AB0000000001} - 请注意,FFFF 代替 1033,这意味着它是多语言的。

在您的检测方法中,您需要添加一个 OR 子句,以便它将 GUID 识别为有效安装。

您还应该注意两个问题:

1) 您应该在检测方法中指定版本号。Reader 11 的所有版本都具有相同的 GUID(即 11.0.1 与 11.0.7 相同),因此如果用户使用的是旧版本,这将导致您的检测方法返回误报。

2) 如果您关心 Reader 的安全补丁,那么您应该知道 Adob​​e 只针对 MUI 版本发布补丁。如果不卸载/重新安装整个产品,您无法使用其 MSI 从 11.0.1 升级到 11.0.7。如果您尝试这样做,它只会告诉您产品已安装(因为 GUID 相同)。

这里是正确的使用 SCCM 管理 Adob​​e Reader 的方法:您的应用程序中需要两种部署类型。

1)按照您已有的方式配置 11.0.0 MSI(确保检测方法指定了版本号 11.0.00 - 不要仅使用 GUID)并保存并关闭它。

2) 返回并添加另一种部署类型。这次,选择脚本安装程序作为类型(SCCM 本身不处理 MSP 文件)。将其指向您的 MSP 文件并使用 msiexec /update(而不是通常的 msiexec /i)作为命令行。对于检测方法,使用相同的 GUID,但版本为 11.0.07(或其他)。将第一个部署类型指定为其依赖项。然后确保补丁在列表中具有更高的优先级。现在保存并再次关闭它。

现在,当未安装阅读器的客户端请求该应用程序时,将同时安装这两个版本。如果该用户已安装 EXE 版本,则会对其进行修补。如果已修补,则只会显示为已安装。

答案2

因此,经过一番研究,我意识到是 Adob​​e Flash Player 让我感到困扰,于是提出了一个可能的假设。据我所知,SCCM 查找以下 WMI 位置:

Namespace: root\CCM\CIModels
Class: CCM_MSIProduct

据我对 WMI 了解,这是由 SCCM 客户端创建的,当您考虑 SCCM 的工作方式时,这会产生一种扭曲的感觉。

我从“部署监控工具”中获取了此位置,您可以在System Center 2012 配置管理器工具包。如果您查看部署区域和“执行”选项卡,您可以查看 DiscoverySourceXML 以查看检测返回的内容。

我今天才发现这一点,所以我还无法完全测试它。这个位置可能只是应用程序发现过程的结果存储。到目前为止,它足以让我知道哪些产品代码适用于 SCCM 应用程序评估过程。

我确实需要一名 SCCM 开发人员看到这个问题并给予我指导。


额外内容

Powershell 脚本列出 WMI 对象:

Get-WmiObject -Namespace root\ccm\CIModels -Class CCM_MSIProduct | Sort-Object ProductName |Format-Table ProductName,ProductCode,ProductVersion

答案3

我可以在哪里看到检测方法正在查询什么以及它返回什么?

我认为 SCCM 中没有办法原生实现这一点,尽管我真的希望有,尤其是对于全局条件。没有什么比在向导中构建检测日志更令人沮丧的了,它没有按预期工作,你只能用不透明的用户界面作为故障排除信息。

我会做的是,找到一台测试计算机(最好是虚拟机,这样你就可以使用快照),它的状况会破坏你的检测逻辑,然后启动进程监控,运行应用程序部署评估周期并查看发现的内容。


执行“Windows 安装程序”检测时,系统在哪里寻找该 GUID?

如果我读微软正确的是 MSI 在 中注册了 ProductCode HKLM\Software\Classes\Installer\Products。一个合理的假设是应用程序检测会检查该位置,同样,您可以使用进程监控



至于 Adob​​e Reader 的可执行安装程序破坏了您的检测逻辑的问题,我在我的“实验室”(即我的工作站)中做了一些测试,并且能够重现您的问题。

我认为所有 Adob​​e Reader 可执行文件所做的就是解压并运行 MSI 安装程序。

Adobe Reader 可执行文件内容

如果你查看内容,setup.ini你会看到所有可执行文件所做的就是启动 MSI 安装程序:

[Startup]
RequireOS=Windows 2000
RequireMSI=3.0
RequireIE=6.0.2600.0

[Product]
msi=AcroRead.msi

无论如何,安装程序确实正确注册了 ProductCode,因此如果您仅以此为依据运行检测逻辑,则两种安装方法之间没有明显的区别。但是,如果您比较可执行安装程序和 MSI 安装程序的注册表项,您会发现一些差异:

从可执行安装程序:

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Installer\Products\68AB67CA7DA73301B744BA0000000010]
"ProductName"="Adobe Reader XI (11.0.06)"
"PackageCode"="08610D4D4ABC0E74BB0257B5EDD58107"

从 MSI 安装程序:

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Installer\Products\68AB67CA7DA73301B744BA0000000010]
"ProductName"="Adobe Reader XI (11.0.06)"
"PackageCode"="26A6583616073E04583DBCA6F0289EEB"

包裹代码不同。安装源也应该不同。

从用户下载的可执行安装程序:

C:\ProgramData\Adobe\Setup\{AC76BA86-7AD7-1033-7B44-AB0000000001}\

从 SCCM 部署的 MSI 安装程序:

C:\Windows\ccmcache\6f\

请注意,SCCM 部署版本来自本地 CCM 缓存。

您可以根据需要将这些添加到您的检测逻辑或要求中,以正确检测这种情况。



答案4

我知道它很旧,但还是忍不住添加我的文章,特别是关于 Win32_Product 的文章,因为它可能会产生负面影响!

我无法对上面的@Dotknuckle 回复发表评论,因此不得不重新回复。Win32_Product 是个坏主意,而且需要更长的时间,因为它会重新注册每个读取此信息的 MSI。http://www.itninja.com/link/why-win32-product-is-bad-news

至于 SMS_InstalledSoftware,它也存在于 SCCM 2012 中,位于命名空间 root\cimv2\sms 下,它比 Win32_Product 更安全,也更快。

同样的原因可能也适用于 CCM_MSIProduct 类,这也是它更快的原因。我使用 SMS_InstalledSoftware,因为它可以返回更多信息。

我一直在 powershell 中使用我自己的自定义检测脚本,它基本上做类似这样的事情。

$SPSS22 = Get-WmiObject -namespace Root\cimv2\sms -class SMS_InstalledSoftware -filter "ARPDisplayName LIKE '%SPSS Statistics%' AND ProductVersion='22.0.0.0'"
If($SPSS22){return $true}

相关内容