1

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

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

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

此外,将 aGet-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)
#>

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

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

4

2 回答 2

5

使用 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使用哈希表作为参数通过参数传递它们。您可以在帮助文件或此处找到示例

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

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

我通常不这样做,因为它与 一起使用的冗长一些-Filter-CLassName并且-Filter缺少 不可用Invoke-CimMethod但是,这些只是个人喜好。

我建议您也阅读CIM Cmdlet 简介

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

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

于 2021-04-07T00:41:51.723 回答
1

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

get-package *visual* | uninstall-package

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

于 2021-04-07T03:36:39.700 回答