powershell - 如何找到已安装的MSI设置的产品GUID?

标签 powershell wix windows-installer installation uninstallation

我需要找到安装了的MSI文件产品GUID ,以便执行诸如 patching uninstall (how-to uninstall)和 auditing purposes的维护。

最佳答案

For upgrade code retrieval: How can I find the Upgrade Code for an installed MSI file?



精简版
下面的信息随着时间的推移已经有了很大的增长,并且可能变得太复杂了。 如何快速获取产品代码? (四种方法):
1-Use the Powershell "one-liner"向下滚动以获取屏幕截图和分步操作。以下免责声明-轻微或中等风险,具体取决于您要求的人。为我工作正常。通常应该可以取消此选项触发的任何自修复。触发
软件包完整性检查确实会添加一些事件日志“噪音”。 请注意! IdentifyingNumber ProductCode(WMI特性)。
get-wmiobject Win32_Product | Format-Table IdentifyingNumber, Name, LocalPackage -AutoSize
Powershell的快速​​入门:按住Windows键,点按R,输入“powershell”,然后按Enter
2-Use VBScript(script on github.com)
在下面的“替代工具”(第3节)下进行介绍。由于下面将详细说明的原因,此选项可能比Powershell的更安全。从本质上讲,它是更快的,并且不能触发MSI自修复,因为它不通过WMI(它以极快的速度直接访问MSI COM API)。但是,它比Powershell选项(几行代码)涉及更多的内容。
3-Registry Lookup有些人发誓要在注册表中查找内容。不是我推荐的方法-我喜欢使用正确的API(或者说:OS函数调用)。总是存在仅由API实现内部解释的奇怪异常:
  • HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
  • HKLM\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall
  • HKCU\Software\Microsoft\Windows\CurrentVersion\Uninstall

  • 4-Original MSI File / WiX Source您可以在任何MSI文件的 Product Code (以及任何其他属性)中找到 Property table 。但是,可以想象,GUID(很少)会在安装时被应用的转换覆盖,因此与注册该产品的GUID不匹配(上述方法1和2将报告实际的产品代码-已在Windows中注册)。罕见的情况)。
    您需要一个工具来查看MSI文件。请参阅以下答案的底部,以获取可以下载的免费工具的列表(或参见下面的快速选项):How can I compare the content of two (or more) MSI files?
    更新:为了方便起见,并且需要速度 :-),立即从SuperOrca下载this direct-download hotlink,不必大惊小怪-该工具足以完成工作-安装,打开MSI并直接进入Property table并找到ProductCode行(,请始终检查直接下载的热链接-显然是-您可以使用virustotal.com这样做-使用数十种防病毒和恶意软件套件进行在线扫描,以扫描您上传的内容)。

    Orca is Microsoft's own tool, it is installed with Visual Studio and the Windows SDK. Try searching for Orca-x86_en-us.msi - under Program Files (x86) and install the MSI if found.

    • Current path: C:\Program Files (x86)\Windows Kits\10\bin\10.0.17763.0\x86
    • Change version numbers as appropriate


    在下面,您将找到原始答案,它“有机地增长”了很多细节。
    如果这是您需要执行的任务,请参见下面的“卸载MSI软件包”部分。

    检索产品代码

    UPDATE: If you also need the upgrade code, check this answer: How can I find the Upgrade Code for an installed MSI file? (retrieves associated product codes, upgrade codes & product names in a table output - similar to the one below).

    • Can't use PowerShell? See "Alternative Tools" section below.
    • Looking to uninstall? See "Uninstall MSI packages" section below.

    启动 Powershell (按住Windows键,点按R,释放Windows键,键入“powershell”,然后按OK)并运行以下命令,以获取已安装的MSI软件包产品代码的列表。本地高速缓存程序包路径产品名称(最大化PowerShell窗口以避免名称被截断)。
    在运行此命令行之前,请阅读下面的免责声明(没有危险,只是一些潜在的麻烦)。 “替代工具”下的第3节演示了使用VBScript获得相同信息的另一种非WMI方法。如果您尝试卸载软件包,则下面有一些示例msiexec.exe命令行的部分:
    get-wmiobject Win32_Product | Format-Table IdentifyingNumber, Name, LocalPackage -AutoSize
    
    输出应该类似于以下内容:

    注意! 出于某种奇怪的原因,在WMI中将“ProductCode” 称为“IdentifyingNumber” 。因此,换句话说-在IdentifyingNumber上方的图片中,是产品代码
    如果您需要对许多远程计算机远程运行此查询,请参见下面的“从远程计算机检索产品代码”一节。

    DISCLAIMER (important, please read before running the command!): Due to strange Microsoft design, any WMI call to Win32_Product (like the PowerShell command below) will trigger a validation of the package estate. Besides being quite slow, this can in rare cases trigger an MSI self-repair. This can be a small package or something huge - like Visual Studio. In most cases this does not happen - but there is a risk. Don't run this command right before an important meeting - it is not ever dangerous (it is read-only), but it might lead to a long repair in very rare cases (I think you can cancel the self-repair as well - unless actively prevented by the package in question, but it will restart if you call Win32_Product again and this will persist until you let the self-repair finish - sometimes it might continue even if you do let it finish: How can I determine what causes repeated Windows Installer self-repair?).

    And just for the record: some people report their event logs filling up with MsiInstaller EventID 1035 entries (see code chief's answer) - apparently caused by WMI queries to the Win32_Product class (personally I have never seen this). This is not directly related to the Powershell command suggested above, it is in context of general use of the WIM class Win32_Product.


    您还可以列表形式(而不是表格)获得输出:
    get-wmiobject -class Win32_Product
    
    在这种情况下,输出类似于以下内容:

    从远程计算机检索产品代码
    从理论上讲,您应该只可以在命令本身中指定一个远程计算机名称。这是与在机器“RemoteMachine”上运行的上述命令相同的命令(已添加-ComputerName RemoteMachine部分):
    get-wmiobject Win32_Product -ComputerName RemoteMachine | Format-Table IdentifyingNumber, Name, LocalPackage -AutoSize
    
    如果您以适当的域上的域管理员权限运行,这可能会起作用。在工作组环境(小型办公室/家庭网络)中,您可能必须直接将用户凭据添加到WMI调用中才能使其工作。
    此外,WMI中的远程连接受(至少) Windows防火墙 DCOM设置用户帐户控制(UAC)(以及任何其他非Microsoft因素影响,例如实际防火墙第三方软件防火墙,各种安全软件等)。它是否可以工作取决于您的确切设置。
  • Setting up a Remote WMI Connection
  • Connecting to WMI Remotely with PowerShell

  • 更新:可以在以下答案中找到有关远程WMI运行的广泛部分:How can I find the Upgrade Code for an installed MSI file?。看来是防火墙规则,通过注册表调整抑制UAC提示可以使事情在工作组网络环境中正常工作。不建议在安全方面进行更改,但是对我有用。

    替代工具
    PowerShell 需要安装 .NET框架(当前在3.5.1版中似乎是2017年10月)。即使安装了.NET,实际的PowerShell应用程序本身也可能会从计算机中丢失。最后,我相信可以通过各种系统策略和特权来禁用或锁定
    在这种情况下,您可以尝试其他几种方法来检索产品代码。我首选的替代方法是 VBScript -它既快速又灵活(但也可以锁定在某些计算机上,与使用工具相比,脚本编写总是涉及更多一点)。
  • 让我们从内置的Windows WMI工具 :wbemtest.exe开始。
  • 启动wbemtest.exe(按住Windows键,点按R,释放Windows键,键入“wbemtest.exe”,然后按OK)。
  • 单击连接,然后确定( namespace 默认为root \ cimv2),然后再次单击“ connect ”。
  • 单击“查询”,然后键入以下 WQL命令(SQL风格):SELECT IdentifyingNumber,Name,Version FROM Win32_Product,然后单击“使用”(或等效项-该工具将被本地化)。
  • 示例输出屏幕截图(已截断)。不是最好的格式,但是您可以获得所需的数据。 IdentifyingNumber是MSI产品代码:

  • wbemtest.exe
  • 接下来,您可以尝试使用自定义的,功能更强大的WMI工具,例如WMIExplorer.exe
  • Windows中不包括。但是,这是一个非常好的工具。推荐的。
  • 在以下位置查看:https://github.com/vinaypamnani/wmie2/releases
  • 启动该工具,单击“连接”,双击ROOT \ CIMV2
  • 从“查询选项卡”中,键入以下查询SELECT IdentifyingNumber,Name,Version FROM Win32_Product并按Execute。
  • 屏幕快照已跳过,该应用程序需要太多屏幕空间。
  • 最后,您可以尝试使用 VBScript 通过MSI自动化接口(interface)(Windows的核心功能-与WMI无关)通过访问信息。
  • 复制以下脚本,并将其粘贴到桌面上的* .vbs文件中,然后尝试通过双击运行它。您的桌面必须对您可写,或者您可以使用任何其他可写位置。
  • 这不是一个很棒的VBScript。 Terseness已被首选,而不是错误处理和完整性,但是它应该以最小的复杂度来完成这项工作。
  • 在运行脚本的文件夹中创建输出文件(文件夹必须可写)。输出文件称为msiinfo.csv
  • 双击文件以在电子表格应用程序中打开,在导入时选择逗号作为定界符-或-只需在记事本或任何文本查看器中打开文件即可。
  • 在电子表格中打开将允许使用高级排序功能。
  • 此脚本可以轻松地调整为显示a significant amount of further details about the MSI installation。可以在此处找到对此的演示:how to find out which products are installed - newer product are already installed MSI windows

  • ' Retrieve all ProductCodes (with ProductName and ProductVersion)
    Set fso = CreateObject("Scripting.FileSystemObject")
    Set output = fso.CreateTextFile("msiinfo.csv", True, True)
    Set installer = CreateObject("WindowsInstaller.Installer")
    
    On Error Resume Next ' we ignore all errors
    
    For Each product In installer.ProductsEx("", "", 7)
       productcode = product.ProductCode
       name = product.InstallProperty("ProductName")
       version=product.InstallProperty("VersionString")
       output.writeline (productcode & ", " & name & ", " & version)
    Next
    
    output.Close
    

    I can't think of any further general purpose options to retrieve product codes at the moment, please add if you know of any. Just edit inline rather than adding too many comments please.

    You can certainly access this information from within your application by calling the MSI automation interface (COM based) OR the C++ MSI installer functions (Win32 API). Or even use WMI queries from within your application like you do in the samples above using PowerShell, wbemtest.exe or WMIExplorer.exe.



    卸载MSI软件包
    如果您要做的是卸载找到产品代码的MSI软件包,则可以使用提升的命令提示符(搜索 cmd.exe ,右键单击并以admin身份运行来执行以下操作: ):
    选项1 :基本,交互式卸载,无需登录(快速而简单):
    msiexec.exe /x {00000000-0000-0000-0000-00000000000C}
    
    快速参数说明:
    /X = run uninstall sequence
    {00000000-0000-0000-0000-00000000000C} = product code for product to uninstall
    
    如果愿意,您还可以启用(详细)日志记录并以静默方式运行,使我们进入选项2:
    选项2 :使用详细日志记录(对于批处理文件更好)进行无提示卸载:
    msiexec.exe /x {00000000-0000-0000-0000-00000000000C} /QN /L*V "C:\My.log" REBOOT=ReallySuppress
    
    快速参数说明:
    /X = run uninstall sequence
    {00000000-0000-0000-0000-00000000000C} = product code for product to uninstall
    /QN = run completely silently
    /L*V "C:\My.log"= verbose logging at specified path
    REBOOT=ReallySuppress = avoid unexpected, sudden reboot
    
    这里有一个有关MSI卸载
    (用于卸载MSI软件包的不同方法)的全面引用:Uninstalling an MSI file from the command line without using msiexec。有许多不同的卸载方式。
    如果您要编写批处理文件,请查看上面第3节中的链接答案,以了解一些常见和标准的卸载命令行变体。
    以及指向msiexec.exe (command line options)的快速链接(MSDN的msiexec.exe命令行概述)。还有the Technet version

    检索其他MSI属性/信息(f.ex升级代码)

    UPDATE: please find a new answer on how to find the upgrade code for installed packages instead of manually looking up the code in MSI files. For installed packages this is much more reliable. If the package is not installed, you still need to look in the MSI file (or the source file used to compile the MSI) to find the upgrade code. Leaving in older section below:


    如果要获取 UpgradeCode 其他MSI属性,则可以从上图中显示的“ LocalPackage ”指定的位置打开产品的缓存安装MSI(类似:C:\WINDOWS\Installer\50c080ae.msi-这是一个十六进制文件名,在每个系统上都是唯一的)。然后,您在“属性表”表中查找UpgradeCode(可以在转换中重新定义UpgradeCode -确保获得正确的值,您需要以编程方式从系统中检索代码-我将提供一个脚本,但是在缓存的MSI中找到的UpgradeCode通常是正确的
    )。
    要打开缓存的MSI文件,请使用 Orca 或其他打包工具。这里讨论了不同的工具(其中任何一个都可以使用):What installation product to use? InstallShield, WiX, Wise, Advanced Installer, etc。如果您没有安装这样的工具,那么您最好的选择是尝试Super Orca(它简单易用,但未经我广泛测试)。
    更新:这是一个新答案,其中包含有关可用于查看MSI文件的各种免费产品的信息:How can I compare the content of two (or more) MSI files?
    如果已安装Visual Studio,请尝试在Orca-x86_en-us.msi下搜索Program Files (x86)-并安装它(这是Microsoft自己的官方MSI查看器和编辑器)。然后在开始菜单中找到Orca。赶紧去时间:-)。从技术上讲,Orca是作为Windows SDK(不是Visual Studio)的一部分安装的,但是Windows SDK是与Visual Studio安装 bundle 在一起的。 如果您没有安装Visual Studio ,也许您知道有人这样做?只需让他们搜索此MSI并将其发送给您(这是一个很小的mb文件)-应该花费他们几秒钟。 更新:您需要几个CAB文件以及MSI-这些文件在找到MSI的同一文件夹中找到。如果没有,您可以随时下载Windows SDK(它是免费的,但它很大-安装的所有内容都会降低PC的速度)。我不确定SDK的哪一部分安装了Orca MSI。如果您这样做,请在此处编辑并添加详细信息。
  • 这是有关MSI卸载问题的更全面的文章:Uninstalling an MSI file from the command line without using msiexec
  • 这是与类似的文章,另外还有一些其他选项,用于使用注册表或缓存的msi检索MSI信息: Find GUID From MSI File

  • 相似的主题(仅供引用和方便访问-我应该清理此列表):
  • How to find the UpgradeCode and ProductCode of an installed application in Windows 7
  • How can I find the upgrade code for an installed application in C#?
  • Wix: how to uninstall previously installed application that is installed using different installer
  • WiX - Doing a major upgrade on a multi instance install
  • how to find out which products are installed - newer product are already installed MSI windows(使用VBScript)
  • How to uninstall with msiexec using product id guid without .msi file present
  • Find GUID of MSI Package
  • 关于powershell - 如何找到已安装的MSI设置的产品GUID?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29937568/

    相关文章:

    docker - 如何将 docker toolbox、dockerfile、docker-compose 文件捆绑到可执行文件中?

    wix - 使用自定义操作卸载多个产品

    powershell - 使用 powershell 从 FQDN 获取域名

    powershell - 在SharePoint 2013中使用Powershell将列表项复制到另一个子网站列表

    powershell - 跨 session 保存 Powershell 对象

    使用 PowerShell 的 Azure blob 版本保留详细信息

    installation - WiX DisableRegistryReflection ="yes"属性不起作用

    wix - 如何更改 msi 日志文件的默认目录?

    installation - 购买还是构建用于Web部署?

    wix - 自定义操作中的条件