Working with WMI methods

Many WMI classes have methods. Methods allow us to perform some action on the object. A recent question on the forum about using methods made me realise that there are still a lot of people following the old VBScript way of doing things.

We will experiment with the BITS service as it is safe for these purposes.

PS> Get-WmiObject -Class Win32_Service -Filter "Name = 'BITS'"


ExitCode  : 0
Name      : BITS
ProcessId : 928
StartMode : Auto
State     : Running
Status    : OK

Lets have a look at the service and its methods

$service = Get-WmiObject -Class Win32_Service -Filter "Name = 'BITS'"

$service | Get-Member -MemberType method

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

Name
----
Change
ChangeStartMode
Delete
GetSecurityDescriptor
InterrogateService
PauseService
ResumeService
SetSecurityDescriptor
StartService
StopService
UserControlService

So we see methods to stop and start the service

$service.StopService()

PS> Get-Service BITS

Status   Name               DisplayName
------   ----               -----------
Stopped  BITS               Background Intelligent Transfer Ser...

$service.StartService()

PS> Get-Service BITS

Status   Name               DisplayName
------   ----               -----------
Running  BITS               Background Intelligent Transfer Ser...

The person asking the question was trying to use the InvokeMethod method

$service.InvokeMethod('StopService',$Null)

and wondering why it was failing. If you look back to the list of methods above you won’t see InvokeMethod. That’s because it is on the base object. PowerShell, in many instances, doesn’t return the pure .NET object. There are methods and properties added or removed to create the object we normally see.

We can get back to the base object

$service.psbase | gm

And in that list you will see a method called InvokeMethod

PS> $service.psbase.InvokeMethod

OverloadDefinitions
-------------------
System.Object InvokeMethod(string methodName, System.Object[] args)
void InvokeMethod(System.Management.ManagementOperationObserver watcher, string methodName, System.Object[] args)
System.Management.ManagementBaseObject InvokeMethod(string methodName, System.Management.ManagementBaseObject
inParameters, System.Management.InvokeMethodOptions options)
void InvokeMethod(System.Management.ManagementOperationObserver watcher, string methodName,
System.Management.ManagementBaseObject inParameters, System.Management.InvokeMethodOptions options)

Shows us how to use it.

Going for the simplest option

PS> $service.psbase.InvokeMethod("StopService", $null)
0
PS> Get-Service BITS

Status   Name               DisplayName
------   ----               -----------
Stopped  BITS               Background Intelligent Transfer Ser...


PS> $service.psbase.InvokeMethod("StartService", $null)
0
PS> Get-Service BITS

Status   Name               DisplayName
------   ----               -----------
Running  BITS               Background Intelligent Transfer Ser...

PS> Get-WmiObject -Class Win32_Service -Filter "Name = 'BITS'" | Invoke-WmiMethod -Name StopService


PS> Get-Service BITS

Status   Name               DisplayName
------   ----               -----------
Stopped  BITS               Background Intelligent Transfer Ser...


PS> Get-WmiObject -Class Win32_Service -Filter "Name = 'BITS'" | Invoke-WmiMethod -Name StartService


PS> Get-Service BITS

Status   Name               DisplayName
------   ----               -----------
Running  BITS               Background Intelligent Transfer Ser...

These options will work as well

$service | Invoke-WmiMethod -Name StopService
$service | Invoke-WmiMethod -Name StartService

Invoke-WmiMethod -InputObject $service -Name StopService
Invoke-WmiMethod -InputObject $service -Name StartService

My preference is to use the get-wmiobject | invoke-wmimethod pairing as when I am developing I can easily test any filters before I start affecting the service.

Of all of the options using the  InvokeMethod method is the one to avoid as it is more cumbersome and involves more typing

In PowerShell v3 we can use the CIM cmdlets but that is a post for another day

More information on using WMI with PowerShell in PowerShell and WMI – www.manning.com/powershellandwmi

Leave a Reply