Probably a dumb question but, I'm just curious.
Is there a difference between Get-CIMInstance
and Get-WMIObject
when Invoking an Uninstall for an application under the Win32_Product
class? Only reason I ask is because:
Get-CIMInstance
to uninstall an application, will reboot my computer with certain programs.Get-WMIObject
to uninstall an application just runs without rebooting.Also, piping a Get-Member
to any Get-CIMInstance
product, doesn't give me a method to uninstall but, it does using Get-WMIObject
. Is this just how the developers wrote it? Although, Invoke-CIMMethod -Name Uninstall
still works.
Heres what I was doing to uninstall multiple apps using 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()
#>
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)
#>
Pardon the long post, just a curious mind.
Please delete/close if not allowed.
There are lots of differences between using the WMI cmdlets and the newer CIM cmdlets. Get-WMIObject
is deprecated in windows PowerShell and has been removed from PowerShell Core, so the general recommendation is to go with CIM. The methods shouldn't behave differently though, so I can't explain the reboot behavior you mentioned.
The objects returned by 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'
You can discover methods using Get-CimClass
(Get-CimClass win32_process ).CimClassMethods
If you need arguments for a given method they can be passed via the -Arguments
parameter using a hash table as the argument. You can find examples in the help file or here
You can use Invoke-WMIMethod directly too:
Invoke-CimMethod -Query "SELECT * FROM Win32_Process WHERE Name = 'powershell_ise.exe'" -MethodName Terminate
I usually don't do it that way because it's a little less verbose to use -Filter
with -CLassName
, and -Filter
is missing isn't available with Invoke-CimMethod
However, these are just personal preferences.
I recommend you read Introduction to CIM Cmdlets as well
Also, Win32_Product has a bad reputation. If you google it you can get more information but here's an article I quickly found through SO questions: Why Win32_Product is Bad News
As a general rule you should move filtering left in the command. Use the -Query
or -Filter
parameters rather than getting all instances and using a Where{}
afterward. Especially considering the known performance issues with Win32_Product.