Get-WMIObject 卸载与 Get-CIMInstance 卸载

Get-WMIObject Uninstall vs Get-CIMInstance Uninstall

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

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

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

获取 CIM 实例/卸载

这是我使用 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)
#>

长篇见谅post,纯属好奇

如果不允许请delete/close

使用 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

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

中找到示例

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

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

我通常不会那样做,因为将 -Filter-CLassName 一起使用会更简洁一些,并且缺少 -Filter 对于 [=20] 不可用=] 然而,这些只是个人喜好。

我建议你也阅读 Introduction to CIM Cmdlets

另外,Win32_Product名声不好。如果你 google 它你可以获得更多信息,但这是我通过 SO 问题快速找到的一篇文章:Why Win32_Product is Bad News

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

的已知性能问题

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

get-package *visual* | uninstall-package

win32_product class 也是出了名的慢,因为它在使用时会验证所有 msi。