Windows Services Management With WMI (Part 1)

By Marcin Policht (Send Email)
Posted Jan 29, 2003


This series of articles will explain the power of Windows Management Instrumentation (WMI) scripting for managing Windows services. As you will see, WMI not only allows you to remotely control services already installed locally or on remote servers and workstations, but it also provides capability to create or delete services. And unlike ADSI, WMI can be used to change passwords on service accounts (for services running under non-Local System accounts). With Windows Management Instrumentation you can not only remotely control services already installed locally or on remote servers and workstations, but you can also create or delete services. Marcin Policht's latest series discusses the power of WMI scripting for managing Windows services and offers a variety of basic scripts to better manage the Win32_Service class.

Service management is provided by methods and properties of Win32_Service class, residing in the root/cimv2 namespace.

Readers unfamiliar with Windows Management Instrumentation may wish to refer to previous articles that introduced basic WMI concepts: Testing IP connectivity With WMI, Setting Network Parameters Using WMI (Part 2), Setting Network Parameters Using WMI (Part 1), and WMI for Everyone.

Before we start looking more closely into the different methods of the Win32_Service class, we first must find a way to list all instances of this class on a computer. This process, called enumeration, enables us to specify which service we want to manage.

The following script lists values of the Name, DisplayName, StartMode, and State properties of every instance of the Win32_Service class on a target computer that is equivalent to the list of all services installed on this computer. The Name property is the one used by Windows, also present in the registry under HKLM\SYSTEM\CurrentControlSet\Services key. The DisplayName is the more human friendly name. This is the same name that is stored in the registry under the DisplayName entry for each service and also the one displayed after running the NET START command at the Command Prompt. The StartMode property of Win32_Service class can be set to "Automatic," "Manual," or "Disabled," and it determines how (and whether) the service starts. Finally, the State property indicates what state the service is currently in.

To enumerate all services on a target computer, the following script can be used:

sComputer 	= "REPLACE ME !!!!" 'replace this with the name of target computer

'********************************
'*** connect to root/cimv2 namespace on the target computer and
'*** create a collection of instances of Win32_Service class

Set cInstances = GetObject("winmgmts:{impersonationLevel=impersonate}//" &_ 
	sComputer & "/root/cimv2:Win32_Service").Instances_

'********************************
'*** enumerate instances in the loop, for each, list relevant properties

For Each oInstance In cInstances
	WScript.Echo "Name:" & vbTab & vbTab & oInstance.Properties_("Name").Value
	WScript.Echo "DisplayName:" & vbTab & oInstance.Properties_("DisplayName").Value
	WScript.Echo "StartMode:" & vbTab & oInstance.Properties_("StartMode").Value
	WScript.Echo "State:" & vbTab & vbTab & oInstance.Properties_("State").Value
	WScript.Echo
Next

This script allows us to retrieve the value of the Name property for each service. Once this is available, we can continue to take advantage of the methods of Win32_Service class, allowing us to start, stop, pause, and resume services.

Starting services is made possible via StartService method of Win32_Service class. The following script illustrates logic used to invoke the StartService method.

sComputer 	= "REPLACE ME !!!!"	'replace with name of target computer
sService	= "Browser"		'replace with name of the service to be started

Set oInstance = GetObject("winmgmts:{impersonationLevel=impersonate}//" & sComputer & _
	"/root/cimv2:Win32_Service=" & Chr(34) & sService & Chr(34))
Set oOutParam = oInstance.ExecMethod_("StartService")

If oOutParam.ReturnValue = 0 Then
	WScript.Echo oInstance.Name & " started successfully"
Else
	WScript.Echo oInstance.Name & " failed to start"
	Select Case oOutParam.ReturnValue
		Case 1	WScript.Echo "The request is not supported."
		Case 2	WScript.Echo "The user did not have the necessary access."
		Case 3	WScript.Echo "The service cannot be started because it depends " & _
					"on other services that are not running."
		Case 4	WScript.Echo "The requested control code is not valid, or " & _
					"it is unacceptable to the service."
		Case 5	WScript.Echo "The requested control code cannot be sent to " & _
					"the service because the state of the service."
		Case 6	WScript.Echo "The service has not been started."
		Case 7	WScript.Echo "The service did not respond to the start request " & _
					"in a timely fashion."
		Case 8	WScript.Echo "Unknown failure when starting the service."
		Case 9	WScript.Echo "The directory path to the service executable was not found."
		Case 10	WScript.Echo "The service is already running"
		Case 11	WScript.Echo "The database to add a new service is locked."
		Case 12	WScript.Echo "A dependency for which this service relies on " & _
					"has been removed from the system."
		Case 13	WScript.Echo "The service failed to find the service needed " & _
					"from a dependent service."
		Case 14	WScript.Echo "The service has been disabled from the system."
		Case 15	WScript.Echo "The service does not have the correct authentication " & _
					"to run on the system."
		Case 16	WScript.Echo "This service is being removed from the system."
		Case 17	WScript.Echo "There is no execution thread for the service."
		Case 18	WScript.Echo "There are circular dependencies when starting the service."
		Case 19	WScript.Echo "There is a service running under the same name."
		Case 20	WScript.Echo "There are invalid characters in the name of the service."
		Case 21	WScript.Echo "Invalid parameters have been passed to the service."
		Case 22	WScript.Echo "The account, which this service is to run under is " & _
					"either invalid or lacks the permissions to run the service."
		Case 23	WScript.Echo "The service exists in the database of services " & _
					"available from the system."
		Case 24	WScript.Echo "The service is currently paused in the system."
	End Select
End If

As you can imagine, a script to stop a service is very similar (with the exception of method invoked by ExecMethod_ and interpretation of returned integer codes). As before, the name of the target computer and the name of the service to be stopped must be verified.

sComputer 	= "REPLACE ME !!!!" 	'replace with name of target computer
sService	= "Browser"		'replace with name of the service to be stopped

Set oInstance = GetObject("winmgmts:{impersonationLevel=impersonate}//" & sComputer & _
	"/root/cimv2:Win32_Service=" & Chr(34) & sService & Chr(34))
Set oOutParam = oInstance.ExecMethod_("StopService")

If oOutParam.ReturnValue = 0 Then
	WScript.Echo oInstance.Name & " stopped successfully"
Else
	WScript.Echo oInstance.Name & " failed to stop"
	Select Case oOutParam.ReturnValue
		Case 1	WScript.Echo "The request is not supported."
		Case 2	WScript.Echo "The user did not have the necessary access."
		Case 3	WScript.Echo "The service cannot be stopped because other " & _
					"services that are running are dependent on it."
		Case 4	WScript.Echo "The requested control code is not valid, or " & _
					"it is unacceptable to the service."
		Case 5	WScript.Echo "The requested control code cannot be sent to " & _
					"the service because the state of the service."
		Case 6	WScript.Echo "The service has not been started."
		Case 7	WScript.Echo "The service did not respond to the stop request " & _
					"in a timely fashion."
		Case 8	WScript.Echo "Unknown failure when stopping the service."
		Case 9	WScript.Echo "The directory path to the service executable was not found."
		Case 10	WScript.Echo "The service is already stopped"
		Case 11	WScript.Echo "The service database is locked."
		Case 12	WScript.Echo "A dependency which this service relies on " & _
					"has been removed from the system."
		Case 13	WScript.Echo "The service failed to find the service needed " & _
					"from a dependent service."
		Case 14	WScript.Echo "The service has been disabled from the system."
		Case 15	WScript.Echo "The service does not have the correct authentication " & _
					"to run on the system."
		Case 16	WScript.Echo "This service is being removed from the system."
		Case 17	WScript.Echo "There is no execution thread for the service."
		Case 18	WScript.Echo "There are circular dependencies when stopping the service."
		Case 19	WScript.Echo "There is a service running under the same name."
		Case 20	WScript.Echo "There are invalid characters in the name of the service."
		Case 21	WScript.Echo "Invalid parameters have been passed to the service."
		Case 22	WScript.Echo "The account, which this service is to run under is " & _
					"either invalid or lacks the permissions to run the service."
		Case 23	WScript.Echo "The service exists in the database of services " & _
					"available from the system."
		Case 24	WScript.Echo "The service is currently paused in the system."
	End Select
End If

To pause service, run PauseService method of Win32_Service class (this time without getting into description of returned error code):

sComputer 	= "REPLACE ME !!!!"	'replace with name of target computer
sService	= "Browser"		'replace with name of the service to be paused

Set oInstance = GetObject("winmgmts:{impersonationLevel=impersonate}//" & sComputer & _
	"/root/cimv2:Win32_Service=" & Chr(34) & sService & Chr(34))
Set oOutParam = oInstance.ExecMethod_("PauseService")

If oOutParam.ReturnValue = 0 Then
	WScript.Echo oInstance.Name & " paused successfully"
Else
	WScript.Echo oInstance.Name & " failed to pause"
End If

Resuming service (after it has been paused) is just as easy:

sComputer 	= "REPLACE ME !!!!"	'replace with name of target computer
sService	= "Browser"		'replace with name of the service to be resumed

Set oInstance = GetObject("winmgmts:{impersonationLevel=impersonate}//" & sComputer & _
	"/root/cimv2:Win32_Service=" & Chr(34) & sService & Chr(34))
Set oOutParam = oInstance.ExecMethod_("ResumeService")

If oOutParam.ReturnValue = 0 Then
	WScript.Echo oInstance.Name & " resumed successfully"
Else
	WScript.Echo oInstance.Name & " failed to resume"
End If

The second article of this series will present more complex scripts dealing with modifying the service properties. It will also cover deleting and creating services.

Page 1 of 1


Comment and Contribute

Your name/nickname

Your email

(Maximum characters: 1200). You have characters left.