【问题标题】:Get-WMIObject Uninstall vs Get-CIMInstance UninstallGet-WMIObject 卸载与 Get-CIMInstance 卸载
【发布时间】:2021-07-02 19:04:27
【问题描述】:

可能是一个愚蠢的问题,但我只是好奇。

在为 Win32_Product 类下的应用程序调用卸载时,Get-CIMInstanceGet-WMIObject 之间有区别吗?我问的唯一原因是:

  • 使用Get-CIMInstance 卸载应用程序,将使用某些程序重新启动我的计算机。
  • 使用Get-WMIObject 卸载应用程序无需重新启动即可运行。

另外,通过管道将Get-Member 传递给任何Get-CIMInstance 产品,并没有给我提供卸载方法,但它确实使用Get-WMIObject。开发人员就是这样写的吗?虽然,Invoke-CIMMethod -Name Uninstall 仍然有效。

获取 CIMInstance / 卸载

这是我使用 Get-CIMInstance/Invoke-CIMMethod -Name Uninstall 卸载多个应用程序所做的:

Get-CimInstance -ClassName win32_product | Where-Object Name -Match "Visual" | 
    ForEach-Object -Process { 
        Invoke-CimMethod -InputObject $_ -Name Uninstall 
                            }
#Methods Returned
<#
Get-CimInstance -ClassName win32_product | Where-Object Name -Match "Visual" | Get-Member -MemberType Method


   TypeName: Microsoft.Management.Infrastructure.CimInstance#root/cimv2/Win32_Product

Name                      MemberType Definition
----                      ---------- ----------
Clone                     Method     System.Object ICloneable.Clone()
Dispose                   Method     void Dispose(), void IDisposable.Dispose()
Equals                    Method     bool Equals(System.Object obj)
GetCimSessionComputerName Method     string GetCimSessionComputerName()
GetCimSessionInstanceId   Method     guid GetCimSessionInstanceId()
GetHashCode               Method     int GetHashCode()
GetObjectData             Method     void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Ser...
GetType                   Method     type GetType()
ToString                  Method     string ToString()
#>

获取 WMIObject / 卸载

Get-WMIObject -ClassName win32_product | Where-Object Name -Match "Visual" | 
    ForEach-Object -Process { 
        Invoke-WMIMethod -InputObject $_ -Name Uninstall 
                            }
#Methods Returned
<#
Get-WMIObject -Class win32_product | Where-Object Name -Match "Visual" | Get-Member -MemberType Method


   TypeName: System.Management.ManagementObject#root\cimv2\Win32_Product

Name      MemberType Definition
----      ---------- ----------
Configure Method     System.Management.ManagementBaseObject Configure(System.UInt16 InstallState, System.UInt16 InstallLevel, S...
Reinstall Method     System.Management.ManagementBaseObject Reinstall(System.UInt16 ReinstallMode)
Uninstall Method     System.Management.ManagementBaseObject Uninstall()
Upgrade   Method     System.Management.ManagementBaseObject Upgrade(System.String PackageLocation, System.String Options)
#>

请原谅这篇长文,只是一个好奇的头脑。

如果不允许,请删除/关闭。

【问题讨论】:

    标签: powershell wmi cim powershell-5.1


    【解决方案1】:

    使用 WMI cmdlet 和较新的 CIM cmdlet 之间存在许多差异。 Get-WMIObject 在 Windows PowerShell 中已弃用,并已从 PowerShell Core 中删除,因此一般建议使用 CIM。不过,这些方法的行为不应有所不同,因此我无法解释您提到的重启行为。

    Get-CimInstance don't have the methods, but you can pass them to Invoke-CimMethod` 返回的对象。

    $instance = Get-CimInstance win32_process -Filter "Name = 'powershell_ise.exe'"
    $instance | Invoke-CimMethod -MethodName 'Terminate'
    

    您可以使用Get-CimClass 发现方法

    (Get-CimClass win32_process ).CimClassMethods
    

    如果您需要给定方法的参数,可以使用哈希表作为参数通过-Arguments 参数传递它们。您可以在帮助文件或here

    中找到示例

    你也可以直接使用 Invoke-WMIMethod:

    Invoke-CimMethod -Query "SELECT * FROM Win32_Process WHERE Name = 'powershell_ise.exe'" -MethodName Terminate
    

    我通常不这样做,因为将-Filter-CLassName 一起使用会不那么冗长,而-Filter is missing 不适用于Invoke-CimMethod 但是,这些只是个人喜好。

    我建议你也阅读Introduction to CIM Cmdlets

    此外,Win32_Product 的名声也很差。如果你用谷歌搜索,你可以获得更多信息,但这是我通过 SO 问题快速找到的一篇文章:Why Win32_Product is Bad News

    作为一般规则,您应该在命令中向左移动过滤。使用-Query-Filter 参数,而不是获取所有实例并在之后使用Where{}。特别是考虑到 Win32_Product 的已知性能问题。

    【讨论】:

    • 你好史蒂文!感谢您的回答。我知道Get-Ciminstance 是继任者,我试图在不使用 WQL 过滤的情况下使其更易读(:我完全忘记了 win32_products 重新配置,因为它是我从文章中最大的收获,除了它是 ” dog slow" 大声笑所以在您看来,您认为从注册表中查询卸载字符串以使用 Posh 卸载程序更好吗?我还希望有人知道为什么它会以 Get-Ciminstance 而不是Get-WMIObject.
    • 在 cmets 中看到有人引用此链接:csi-windows.com/toolkit/win32product-replacement。似乎找到了 win32_product 卸载的替代方法,但是由于它的 VBScript,我很难理解它的真正作用。也感谢您提供的链接。 “CIM cmdlet 简介”已经过了一半。真的很好读。
    • 完全不熟悉 Invoke-WMIMethod 能够从一开始就做我需要的事情,而无需使用 Get-Ciminstance 查询应用程序。
    • 尽管有 WMI/CIM 的细节,如果是我,我可能会从卸载注册表项中查找卸载字符串,然后单独运行它,也许还有一些控制和监视功能。
    • blog.ipswitch.com/… CIM 与 WMI 的好文章
    【解决方案2】:

    或者使用 get-package,假设它是一个 msi 安装:

    get-package *visual* | uninstall-package
    

    众所周知,win32_product 类的速度也很慢,因为它会在使用时验证所有 msi。

    【讨论】:

    • 你提到这个原因很有趣,我尝试Uninstall-Package 没有运气。至少期待错误,但它确实显示任何内容,并且状态仍处于已安装状态。甚至尝试重新启动以查看它是否会卸载,但是也没有运气;还在那儿。卸载注册表中的字符串也没有帮助。
    • 对于卸载的特定问题,我喜欢这个想法。但如果您想在非本地操作,则必须使用 PoSh 远程处理。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-21
    • 1970-01-01
    • 2021-10-01
    • 2016-11-29
    • 1970-01-01
    • 1970-01-01
    • 2012-11-06
    相关资源
    最近更新 更多