Page 1 of 1 1
Topic Options
#181662 - 2007-10-16 12:29 PM Determine if a service is in running state
BunzyBuddy Offline
Fresh Scripter

Registered: 2006-02-22
Posts: 40
Loc: Amsterdam, Holland
Hi all,
I'm trying to write a KIX script wich will do 2 diffrent things depending on a certain service is in running or in stopped state.

So:

If service x is running
Do this....
If service x is not running
Do that....

How can I determine if a service is running or not ?

Thanks for your help !

Greetings

Top
#181665 - 2007-10-16 01:40 PM Re: Determine if a service is in running state [Re: BunzyBuddy]
Glenn Barnas Administrator Offline
KiX Supporter
*****

Registered: 2003-01-28
Posts: 4396
Loc: New Jersey
You can search the UDF collection for fnWMIService, or try the code I'm working on. This code is 90% complete - only the CREATE SERVICE action is yet to be written.

With this code, you can use:

If WMISvcMgr('Query', 'W32Time', , $Computer)[7] = 'Running'
  'Is Running!'
EndIf

It also illustrates how you can use WMI to query and manage services.


;; 
;;====================================================================== 
;; 
;;FUNCTION       WMISvcMgr() 
;; 
;;ACTION         Manage windows services 
;; 
;;AUTHOR         Glenn Barnas 
;; 
;;VERSION        1.0 / 2007/10/15 
;;		 Written as a replacement for SvcList() & SvcCtl(), which uses XNET.exe 
;; 
;;SYNTAX         WMISvcMgr(Action, [Service] [, SvcData] [, Computer] [, AuthPtr]) 
;; 
;;PARAMETERS     Action	  - REQUIRED, Action to perform - must be one of: 
;;			Error#	- return WMI_Service error message 
;;			List	- list all services and their status 
;;			Start	- start the named service 
;;			Stop	- stop the named service 
;;			Create	- create the named service using the supplied configuration array 
;;			Modify	- modify the named service using the supplied configuration array 
;;			Delete	- delete the named service 
;;			Query	- return current service data in the configuration array 
;; 
;;		 Service  - OPTIONAL, Name of service to act upon 
;; 
;;		 SvcData  - OPTIONAL, Array of service parameters 
;;			 0 - service short name	 
;;			 1 - DisplayName	 
;;			 2 - PathName		 
;;			 3 - ServiceType	 
;;			 4 - ErrorControl	 
;;			 5 - StartMode		Disabled, Manual, or Automatic 
;;			 6 - DesktopInteract	 
;;			 7 - State		(only when reading, ignored when writing) 
;;			 8 - StartName		 
;;			 9 - StartPassword	(only when writing, always returned empty) 
;; 
;;		 Computer - OPTIONAL, Name of computer to query 
;; 
;;               AuthPtr - OPTIONAL - pre-authenticated WMI object pointer 
;;                 Use WMIAuthentication() udf to create the AuthPtr value 
;;                 AuthPtr is not needed if user has admin rights 
;; 
;;REMARKS        Used to manipulate & query services on a local or remote system 
;;		    
;; 
;;RETURNS        Depends upon action 
;;			List	- Array of comma-delimited values: short name, display name, status 
;;			Start	- WMI_Service status code 
;;			Stop	- WMI_Service status code 
;;			Create	- WMI_Service status code 
;;			Modify	- WMI_Service status code 
;;			Delete	- WMI_Service status code 
;;			Query	- Array of service information (SvcData format) 
;; 
;;DEPENDENCIES   WMI 
;; 
;;TESTED WITH    W2K, WXP, W2K3, Vista, x64 
;; 
;;EXAMPLES        
; 
Function WMISvcMgr($_Action, OPTIONAL $_Service, OPTIONAL $_Data, OPTIONAL $_Target, OPTIONAL $_pAuth)
 
  Dim $_objWMI, $_cItems, $_oItem		; WMI object vars 
  Dim $_Line					; line string 
  Dim $_aTmp[0], $_I				; return array, index 
  Dim $_					; temp var 
  Dim $_BTime, $_CTime				; boot and current times from target system 
 
  ; If a numeric value was provided for Action, return the WMI_Service status/error message string 
  If $_Action = Int($_Action)
    Select
     Case $_Action =  0 $WMISvcMgr = 'Action completed successfully'
     Case $_Action =  1 $WMISvcMgr = 'Not Supported'
     Case $_Action =  2 $WMISvcMgr = 'Access Denied'
     Case $_Action =  3 $WMISvcMgr = 'Start failed - dependent service(s) not running'
     Case $_Action =  4 $WMISvcMgr = 'Invalid Service Control Request'
     Case $_Action =  5 $WMISvcMgr = 'Service cannot accept the requested control'
     Case $_Action =  6 $WMISvcMgr = 'Service Not Active'
     Case $_Action =  7 $WMISvcMgr = 'Service Request Timeout'
     Case $_Action =  8 $WMISvcMgr = 'Unknown failure when starting service'
     Case $_Action =  9 $WMISvcMgr = 'Path not found'
     Case $_Action = 10 $WMISvcMgr = 'Service Already Running'
     Case $_Action = 11 $WMISvcMgr = 'Service Database Locked'
     Case $_Action = 12 $WMISvcMgr = 'Service Dependency Deleted'
     Case $_Action = 13 $WMISvcMgr = 'Service Dependency Failure'
     Case $_Action = 14 $WMISvcMgr = 'Service Disabled'
     Case $_Action = 15 $WMISvcMgr = 'Service Logon Failure'
     Case $_Action = 16 $WMISvcMgr = 'Service Markded for Deletion'
     Case $_Action = 17 $WMISvcMgr = 'No Service Execution Thread'
     Case $_Action = 18 $WMISvcMgr = 'Circular Dependency'
     Case $_Action = 19 $WMISvcMgr = 'Duplicate Name'
     Case $_Action = 20 $WMISvcMgr = 'Invalid Name'
     Case $_Action = 21 $WMISvcMgr = 'Invalid Service Parameter(s)'
     Case $_Action = 22 $WMISvcMgr = 'Invalid Service Account'
     Case $_Action = 23 $WMISvcMgr = 'Service Exists'
     Case $_Action = 24 $WMISvcMgr = 'Already Paused'
    Exit 0
  EndIf
 
 
  ; insure we have a valid target name, without any "\" 
  $_Target = IIf($_Target, $_Target, '.')
  If InStr($_Target, '\') $_Target = Join(Split($_Target, '\'), '') EndIf
  ; If we pre-authenticated via WMIAuth, use that WMIobject instead, otherwise instantiate an object reference 
  If $_pAuth
    $_objWMI = $_pAuth
  Else
    $_objWMI = GetObject('winmgmts:{impersonationLevel=impersonate}!\\' + $_Target + '\root\cimv2')
    If @ERROR Exit Val('&' + Right(DecToHex(@ERROR), 4)) EndIf
  EndIf
 
 
  ; Verify that the Service name is provided for actions that require it 
  If InStr('-Start-Stop-Create-Modify-Delete-Query-', '-' + $_Action + '-')
    If $_Service = '' Exit 87 EndIf
  EndIf
 
 
  ; Create the collection of all services, or one specific one, depending on action 
  If InStr('-List-Create-', '-' + $_Action + '-')
    $_cItems = $_objWMI.ExecQuery('Select * from Win32_Service')
  Else
    ; All remaining Actions require a service name - either exit if not definee or query WMI 
    $_cItems = $_objWMI.ExecQuery('Select * from Win32_Service WHERE Name = "' + $_Service + '"')
  EndIf
 
 
  ; validate the action and required arguments, perform the defined task 
  Select
   ; ============================== 
   Case $_Action = 'List'   
    $_I = -1
    For Each $_oItem in $_cItems 
      $_I = $_I + 1
      ReDim Preserve $_aTmp[$_I]
      $_aTmp[$_I]= $_oItem.name + ',' + $_oItem.DisplayName + ',' + $_oItem.State
    Next
    $WMISvcMgr = $_aTmp
    $_cItems = 0
    Exit 0
 
   ; ============================== 
   Case $_Action = 'Create'
    If VarType($_SvcData) < 8192 Exit 87 EndIf	; exit if service data array is not defined 
; TBD 
 
   ; ============================== 
   Case $_Action = 'Modify'
    If VarType($_SvcData) < 8192 Exit 87 EndIf	; exit if service data array is not defined 
    If UBound($_SvcData) <> 9 Exit 87 EndIf	; exit if service data array is invalid 
    ; Change(DisplayName, PathName, ServiceType, ErrorControl, StartMode, DesktopInteract, StartName, StartPassword,  
    ; next 3 unsupported... 
    ; LoadOrderGroup, LoadOrderGroupDependencies, ServiceDependencies) 
    For Each $_oItem in $_cItems
      $_R = $_oItem.Change($_Data[1],$_Data[2],$_Data[3],$_Data[4],$_Data[5],$_Data[6],$_Data[8],$_Data[9])
    Next
 
   ; ============================== 
   Case $_Action = 'Query'
    ReDim $_aTmp[9]
    For Each $_oItem in $_cItems
      $_aTmp[0]  = $_oItem.Name				; Service Name (not modifiable) 
      $_aTmp[1]  = $_oItem.DisplayName			; Display Name 
      $_aTmp[2]  = $_oItem.PathName			; Binary Path 
      $_aTmp[3]  = $_oItem.ServiceType			; type of service 
      $_aTmp[4]  = $_oItem.ErrorControl			; 0:Ignore, 1:Normal, 2:Severe, 3:Critical 
      $_aTmp[5]  = $_oItem.StartMode			; Start Mode 
      $_aTmp[6]  = $_oItem.DesktopInteract		; Bool - true if service can interact with desktop 
      $_aTmp[7]  = $_oItem.State			; Current state (Read Only) 
      $_aTmp[8]  = $_oItem.StartName			; Service User Account 
      $_aTmp[9]  = '' ; $_oItem.StartPassword		; Service password (not readable, return null) 
    Next
    $WMISvcMgr = $_aTmp
    Exit @ERROR
 
   ; ============================== 
   Case $_Action = 'Start'
    For Each $_oItem in $_cItems 
      $WMIService = $_oItem.StartService
      $_R $_oItem.StopService
      $_E = @ERROR
    Next
 
   ; ============================== 
   Case $_Action = 'Stop'
    For Each $_oItem in $_cItems 
      $_R = $_oItem.StopService
      $_E = @ERROR
    Next
 
   ; ============================== 
   Case $_Action = 'Delete'
    For Each $_oItem in $_cItems 
      $WMIService = $_oItem.DeleteService
      $_R $_oItem.StopService
      $_E = @ERROR
    Next
 
  EndSelect
 
  $WMISvcMgr = $_R ; Not @ERROR 
  Exit $_E
 
EndFunction
 
 
_________________________
Actually I am a Rocket Scientist! \:D

Top
#181666 - 2007-10-16 01:52 PM Re: Determine if a service is in running state [Re: Glenn Barnas]
Glenn Barnas Administrator Offline
KiX Supporter
*****

Registered: 2003-01-28
Posts: 4396
Loc: New Jersey
Here are a few examples of using my function:
 Code:
; list all services on local computer
$a = WMISvcMgr('List') 
@SERROR ?
For Each $ in $a
 Left(Split($, ',')[0] + '                                        ', 40) Split($, ',')[2] ?
Next

; display current status
$a = WMISvcMgr('Query', 'Spooler', , $Computer) 
UBound($a) + 1 ' records' ?
@SERROR ?
For Each $ in $a
 $ ?
Next

; Stop the service
WMISvcMgr('Stop', 'Spooler', , $Computer) ?
@SERROR ?
Sleep 1

; show current status
$a = WMISvcMgr('Query', 'Spooler', , $Computer) 
@SERROR ?
For Each $ in $a
 $ ?
Next

; Stop the service (again) and handle special message
$Err = WMISvcMgr('Stop', 'Spooler', , $Computer)
@SERROR ?
WMISvcMgr($Err) ?

Sleep 1

; Start the service
WMISvcMgr('Start', 'Spooler', , $Computer)  ?
@SERROR ?
Sleep 1

; show updated status
$a = WMISvcMgr('Query', 'Spooler', , $Computer) @SERROR ?
For Each $ in $a
 $ ?
Next
_________________________
Actually I am a Rocket Scientist! \:D

Top
#181667 - 2007-10-16 02:11 PM Re: Determine if a service is in running state [Re: Glenn Barnas]
Jochen Administrator Offline
KiX Supporter
*****

Registered: 2000-03-17
Posts: 6380
Loc: Stuttgart, Germany
Call me old fashioned, but I still shell out to xnet.exe (maybe because it is written by Ruud so it feels less shell'd out ;\) )

shell '%ComSpec% /c [path\]xnet list [\\Remotename\]ServiceDisplayname | find /c "Running" >nul 2>nul'

check @error afterwards, if it is 0, the service is running else it is not
_________________________



Top
#181668 - 2007-10-16 02:18 PM Re: Determine if a service is in running state [Re: Jochen]
Jochen Administrator Offline
KiX Supporter
*****

Registered: 2000-03-17
Posts: 6380
Loc: Stuttgart, Germany
If you need to do this only locally, you may also do something like this:

 Code:
shell '%ComSpec% /c net start |find /c "Print Spooler" >nul 2>nul'
if not @error
    "Spooler Service is running"
else
    "No printing today, try tomorrow :p"
endif
_________________________



Top
#181670 - 2007-10-16 03:41 PM Re: Determine if a service is in running state [Re: Jochen]
Glenn Barnas Administrator Offline
KiX Supporter
*****

Registered: 2003-01-28
Posts: 4396
Loc: New Jersey
Jochen: (aka "Old Fashioned")

I almost posted my SvcList and SvcCtl UDFs, which use XNET. I'm actually upset that XNet is no longer a part of the Kix distribution - it's one of my favorite tools. I'm really bummed that it fails on my Vista x64 system. That's the reason behind the format of the values returned from my new func - it (will) match the results generated by my UDFs that use XNET.

Both of the XNET-based UDFs can be downloaded from the Resources page of my web site.

Glenn
_________________________
Actually I am a Rocket Scientist! \:D

Top
#181682 - 2007-10-16 10:40 PM Re: Determine if a service is in running state [Re: Glenn Barnas]
NTDOC Administrator Offline
Administrator
*****

Registered: 2000-07-28
Posts: 11623
Loc: CA
Curious why you're writing a new one Glenn. The one written up by Chris S. is pretty darn full. What are you planning to have that fnWMIService doesn't have?


Not sure why but http://www.kixtart.org/udf does not appear to list that UDF (maybe due to missing the open/close parens) but here is a link to it.


fnWMIService() - Use the Win32_Service class of WMI to control services


Top
#181683 - 2007-10-16 11:03 PM Re: Determine if a service is in running state [Re: NTDOC]
Glenn Barnas Administrator Offline
KiX Supporter
*****

Registered: 2003-01-28
Posts: 4396
Loc: New Jersey
I need specific input and output to replace existing UDFs that use XNET. I haven't posted this in the UDF forum yet.

fnWMIService is great, especially if you're comfortable with WMI, and programming in general. This UDF is more direct, requiring less setup and programming, as well as being a drop-in replacement for my older UDFs.

I use a modified version of fnWMIService in many other scripts where I need the extra level of control and am willing to code for it. You can find the modified version on my web site. I modify all public WMI code to allow interacting with Sealeapord's WMIAuth UDF.

Glenn
_________________________
Actually I am a Rocket Scientist! \:D

Top
#181687 - 2007-10-17 01:17 AM Re: Determine if a service is in running state [Re: BunzyBuddy]
kholm Offline
Korg Regular
*****

Registered: 2000-06-19
Posts: 714
Loc: Randers, Denmark
If You want to use the names from Services, You could try this
 Code:
Break On
$Service = 'Print Spooler'

If ServiceRunning($Service)
	$Service + ' is Running'
Else
	$Service + ' is NOT Running'
EndIf

Get $x

Function ServiceRunning($ServiceName)
	Dim $oWMI,$cItems,$oItem
	$oWMI = GetObject("winmgmts:root\cimv2")
	$cItems = $oWMI.ExecQuery("Select * From Win32_Service Where Caption='$ServiceName' And Started=-1",,48)
	For Each $oItem In $cItems
	  $ServiceRunning = 1
	Next
EndFunction

-Erik

Top
#181689 - 2007-10-17 03:00 AM Re: Determine if a service is in running state [Re: Glenn Barnas]
NTDOC Administrator Offline
Administrator
*****

Registered: 2000-07-28
Posts: 11623
Loc: CA
Well then that leads to PROPRIETARY UDF which is not a good thing for most users as your UDF mods are not published and maintained here on Korg which means that if they were to become publicly used there could easily become version issues as people would probably come here for assistance and most of the regulars would not have or see your code here to help them.

If current published UDFS don't handle what you're doing then perhaps you should post and ask the author for an update, or (as you've done with a few) post your own UDF so that it is maintained here on Korg and not on your site as the main source.

As an example you and I both worked on the WMIConfirm.udf - if that does not provide what you want or if Jens' does not provide what you want then maybe ask for an updated version.

I know you already know all this stuff Glenn and I'm not meaning to slam you on this (maybe I'm the one just reading you wrong) I just don't want off site UDFs to popup and then users come here asking for help with it.

Top
#181691 - 2007-10-17 04:28 AM Re: Determine if a service is in running state [Re: NTDOC]
Glenn Barnas Administrator Offline
KiX Supporter
*****

Registered: 2003-01-28
Posts: 4396
Loc: New Jersey
Yes, indeed it does. The WMI UDFs are modified to add an optional $_pAuth parameter at the end of the function. The first WMI line, which instantiates the object, is modified to become the Else part of an If/Else statement. If the $_pAuth value is passed, that is used instead of the one opened in the UDF. The remainder of the UDF is generally unchanged. I've PM'd a few regarding this change, and believe that only one was updated. Funny you bring up WMIConfirm, since you and I worked on updating some other code with WMIAuth integration and I suggested you add it to that UDF as well, but the published UDF still does not have the update. ;\)

Honestly, if you look at the library I now publish, I think you'll find that nearly every public UDF has been modified in some way, often simply "de-golfed" to add comments in the code. As sweet as some of Lonk's code can be, I would never be able to have it pass a code review at the organizations I work for. I've added 30 lines of comments to a 10 line UDF to get it through the review process, and often without a single "real" code change. I have strict, documented standards in my organization, especially now that there are several people coding and using the UDF libraries. For example:
  • If a function deals with WMI, the name must begin with "WMI" - no leading chars, and not "WMI" elsewhere in the name. It must accept the pAuth value as the last optional field.
  • If the file is a library of functions, the file name must end in "lib". Libraries must have a header that describes the library, and each function must have a full header.
  • In addition to explicit, NoVars and NoMacros type options, I also need to insure that variable names conform to certain standards - Globals & Macros in ALL CAPS, Function vars must separate the $ from name with a "_" so the variable map file that is generated allows quick visual determination if a var is from main or UDF code. Even variable names between functions should be similar ($_Target, not $_Computer or $_Server or $_System). Most of my UDFs meet this, but we don't usually change varnames in public UDFs. We're still discussing the use of strict Hungarian Notation for variables.
  • Individually DIMming variables or variable sets, with comments describing each var or set. (a "set" is something like Dim $X,$Y,$Z ; loop index vars)

I'm not going to enforce the coding standards of the organization I work for upon others, which is why I choose to modify most public UDFs for internal use. I keep track of changes to the public UDFs, updating the internal code to keep up with updates on a regular basis. And - when I find bugs, I test with the raw code and if the bug is still there, I post not only the finding, but often the solution as well. A recent example is Jens' DirList - found two bugs dealing with deep recursion (one's still outstanding [ Jens - you listening? ;\) ]) I actually use both DirList and DirPlus, but prefer DirList for large file manipulations due to the way it returns data to me. I regularly use it to synchronize files with 60-70 thousand files.

Finally, I published my library because I've been including it with the KixDev toolchest for over 2 years now. It's easier to make my library available to users of my kixtart development tools that way. If someone comes to KORG with questions A) great, that's more traffic here, and B) I'll prolly be here to stick my coins into the discussion. You comment sounds like you're saying we would not discuss UDFs created or adapted from MS or ScriptLogic, and I know that's not what you mean.

Oh - BTW - with all this talk about standards and such... there's one UDF on my site that's very specialized, difficult to read, and has no comments whatsoever. It flies in the face of standards! It only works if you use KGen, and is only useful if you don't tokenize your files. ;\) Lonk would be proud! \:D

Glenn
_________________________
Actually I am a Rocket Scientist! \:D

Top
#181698 - 2007-10-17 06:39 AM Re: Determine if a service is in running state [Re: Glenn Barnas]
NTDOC Administrator Offline
Administrator
*****

Registered: 2000-07-28
Posts: 11623
Loc: CA
Thanks Glenn.

Yes I like your code commenting and standards. Think overall we're in agreement I was just checking.

Top
Page 1 of 1 1


Moderator:  Glenn Barnas, NTDOC, Arend_, Jochen, Radimus, Allen, ShaneEP, Ruud van Velsen, Mart 
Hop to:
Shout Box

Who's Online
0 registered and 248 anonymous users online.
Newest Members
gespanntleuchten, DaveatAdvanced, Paulo_Alves, UsTaaa, xxJJxx
17864 Registered Users

Generated in 0.065 seconds in which 0.027 seconds were spent on a total of 13 queries. Zlib compression enabled.

Search the board with:
superb Board Search
or try with google:
Google
Web kixtart.org