HTA with VBScript to monitor and stop/start windows services

Hello, I'm attempting to write my first HTA script and in doing research I came across this thread:

https://www.experts-exchange.com/questions/24494363/HTA-with-VBScript-to-stop-start-windows-services.html

I'm no programming or scripting expert by any means.. normally I can figure out what I need to do by researching and looking at examples I see on the internet.  So please excuse me if I say anything ignorant.  Now the HTA script I'm writing is incredibly similar to what the user "rejoinder" posted in the above mentioned thread.  So I copied the code and tried to run it on my computer so I can see exactly how it works to try and get an idea of how to make mine work, but all it did was launch the Windows MSI Installer.  I know it is something related to the CLSID in the object in the <BODY> section.  Removing the CLSID from the object will make the script run but it doesn't do anything.  I put the same CLSID into my HTA script I'm writing and that made it launch the Windows Installer also.  I don't know what I'm missing.  Any help in getting this script to work for me would be greatly appreciated.  Thanks in advance!
Dennis DAsked:
Who is Participating?
 
Bill PrewConnect With a Mentor Commented:
Okay, this isn't perfect, and isn't quite as fancy as the activex listview control was, but it's done with just a basic HTML table, so I like the "simple factor" of it.  Take a look and see if it works the way you expect there and maybe this is a building block for you.  Certainly styling can be cleaned up and we could make the table "scroll-able" within a predefined size, but that isn't as simple as we would all like, and takes a bit of time - something I'm running short of this week unfortunately...

And I didn't want to embellish this too much if you didn't think it could be a useful approach.  See what you think...

<head>
<title>Server Services</title>
<HTA:APPLICATION 
     APPLICATIONNAME="Server Services"
     BORDER="thin"
     SCROLL="yes"
     SINGLEINSTANCE="yes"
     ID="oHTA"
>
 <APPLICATION:HTA>
</head>

<style>
body {
    background-color: linen;
    font-family: 'Source Sans Pro', sans-serif;
    font-size: 25px;
}
table {
    background-color: white;
    font-family: 'Source Sans Pro', sans-serif;
    font-size: 12px;
}
th {
    background-color: lightcyan;
}

</style>

<script language="VBScript">
 
Sub Window_OnLoad
    ' Populate table with list of services
    ListServices(".")
End Sub
 
Sub ListServices(sComputer)
    Set oTable = Document.All("list_servicenames")

    ' Delete any existing data rows
    rowCount = oTable.Rows.Length
    If rowCount > 1 Then
        For i = rowCount - 1 To 1 Step -1
            oTable.DeleteRow(i)
        Next
    End If

    ON ERROR RESUME NEXT

    ' Get all services from WMI
    set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & sComputer & "\root\cimv2")
    Set colItems = objWMIService.ExecQuery("Select * from Win32_Service")

    ' For each services add a data row to the table
    For Each objItem in colItems
        Set TR = oTable.InsertRow()
        Set TD = TR.InsertCell()
        TD.InnerHTML = "<input type=""checkbox""></td>"
        Set TD = TR.InsertCell()
        TD.InnerHTML = objItem.Caption
        Set TD = TR.InsertCell()
        TD.InnerHTML = objItem.State
        Set TD = TR.InsertCell()
        TD.InnerHTML = objItem.Name
        Set TD = TR.InsertCell()
        TD.InnerHTML = objItem.Description
        Set TD = TR.InsertCell()
        TD.InnerHTML = objItem.StartMode
    Next
End Sub
 
Sub btn_start_onClick()

    strComputer = "."                                                                                                   
    Set oTable = Document.All("list_servicenames")
    rowCount = oTable.Rows.Length

    ' Process all selected rows of table, Start service
    For i = 1 To rowCount - 1 Step 1
        If UCase(Left(oTable.Rows(i).Cells(0).InnerHTML, 14)) = "<INPUT CHECKED" Then
            strService = oTable.Rows(i).Cells(3).InnerHTML
            Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2") 
            Set colServiceList = objWMIService.ExecQuery ("Select * from Win32_Service where Name='" & strService & "'")
            For each objService in colServiceList                                                                       
                errReturn = objService.StartService()                                                                   
            Next                                                                                                        
        End If                                                                                                          
    Next                                                                                                                

    ' Refresh Service table
    ListServices(strComputer)                                                                                           

End Sub
 
Sub btn_stop_onClick()

    strComputer = "."                                                                                                   
    Set oTable = Document.All("list_servicenames")
    rowCount = oTable.Rows.Length

    ' Process all selected rows of table, Stop service
    For i = 1 To rowCount - 1 Step 1
        If UCase(Left(oTable.Rows(i).Cells(0).InnerHTML, 14)) = "<INPUT CHECKED" Then
            strService = oTable.Rows(i).Cells(3).InnerHTML
            Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2") 
            Set colServiceList = objWMIService.ExecQuery ("Select * from Win32_Service where Name='" & strService & "'")
            For each objService in colServiceList                                                                       
                errReturn = objService.StopService()                                                                    
            Next                                                                                                        
        End If                                                                                                          
    Next                                                                                                                
    ListServices(strComputer)                                                                                           

End Sub
 
Sub btn_restart_onClick()

    strComputer = "."                                                                                                   
    Set oTable = Document.All("list_servicenames")
    rowCount = oTable.Rows.Length

    ' Process all selected rows of table, Stop service
    For i = 1 To rowCount - 1 Step 1
        If UCase(Left(oTable.Rows(i).Cells(0).InnerHTML, 14)) = "<INPUT CHECKED" Then
            strService = oTable.Rows(i).Cells(3).InnerHTML
            Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2") 
            Set colServiceList = objWMIService.ExecQuery ("Select * from Win32_Service where Name='" & strService & "'")
            For each objService in colServiceList                                                                       
                errReturn = objService.StopService()                                                                    
            Next                                                                                                        
        End If                                                                                                          
    Next                                                                                                                

    ' Process all selected rows of table, Start service
    For i = 1 To rowCount - 1 Step 1
        If UCase(Left(oTable.Rows(i).Cells(0).InnerHTML, 14)) = "<INPUT CHECKED" Then
            strService = oTable.Rows(i).Cells(3).InnerHTML
            Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2") 
            Set colServiceList = objWMIService.ExecQuery ("Select * from Win32_Service where Name='" & strService & "'")
            For each objService in colServiceList                                                                       
                errReturn = objService.StartService()                                                                   
            Next                                                                                                        
        End If                                                                                                          
    Next                                                                                                                
    ListServices(strComputer)                                                                                           
End Sub                                                                                                                 
 
Sub btn_Refresh_onClick()
    ListServices(".")
End Sub
 
Sub btn_exit_onClick()
    Window.Close
End Sub
 
</script>
 
<body>

<table border=1 id=list_servicenames> 
<tr> 
<th>Select</td>
<th>Caption</td>
<th>State</td>
<th>Name</td>
<th>Description</td>
<th>Start Mode</td>
</tr> 
</table> 

 
<br />
<input type="button" value="Refresh" name="btn_Refresh" id="btn_Refresh" title="Click to refresh the services list"> &nbsp;
<input type="button" value="Start"   name="btn_start"   id="btn_start"   title="Click to Start the Services"> &nbsp;
<input type="button" value="Stop"    name="btn_stop"    id="btn_stop"    title="Click to Stop the Service"> &nbsp;
<input type="button" value="Restart" name="btn_restart" id="btn_restart" title="Click to Restart the Services"> &nbsp;
<input type="button" value="Exit"    name="btn_exit"    id="btn_exit"    title="Click to Exit Form ">
 
</body>

Open in new window


»bp
0
 
Bill PrewCommented:
Can you post the exact code you are running?


»bp
0
 
Dennis DAuthor Commented:
<head>
<title>Server Services</title>
<HTA:APPLICATION 
     APPLICATIONNAME="Server Services"
     BORDER="thin"
     SCROLL="yes"
     SINGLEINSTANCE="yes"
     ID="oHTA"
>
 <APPLICATION:HTA>
</head>

<script language="VBScript">
 
Sub Window_OnLoad
    
    Set objlst_groupnames = document.getElementById( "list_servicenames" )
    If objlst_groupnames Is Nothing Then
        MsgBox "A problem was encountered while creating the listview." & vbCRLF & "Please see your administrator."
    Else
        With objlst_groupnames
            .View              = 3
            .Width             = 800
            .Height            = 600
            .SortKey           = 0
            .Arrange           = 0
            .LabelEdit         = 1
            .SortOrder         = 0
            .Sorted            = 1
            .MultiSelect       = 0
            .LabelWrap         = -1
            .HideSelection     = -1
            .HideColumnHeaders = 0
            .OLEDragMode       = 0
            .OLEDropMode       = 0
            .Checkboxes        = 1
            .FlatScrollBar     = 0
            .FullRowSelect     = 1
            .GridLines         = 0
            .HotTracking       = 0
            .HoverSelection    = 0
            .PictureAlignment  = 0
            .TextBackground    = 0
            .ForeColor         = -2147483640
            .BackColor         = -2147483643
            .BorderStyle       = 1
            .Appearance        = 1
            .MousePointer      = 0
            .Enabled           = 1
            .ColumnHeaders.Clear
            .ColumnHeaders.Add , , "Caption", 150
            .ColumnHeaders.Add , , "State", 150
            .ColumnHeaders.Add , , "Name", 150
            .ColumnHeaders.Add , , "Description", 150
            .ColumnHeaders.Add , , "Start Mode", 150
            .ListItems.Clear
        End With
    End If
    ListServices(".")
End Sub
 
Sub ListServices(sComputer)
    ON ERROR RESUME NEXT
    Set objList = document.getElementById( "list_servicenames" )
    objList.ListItems.Clear
    
    set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & sComputer & "\root\cimv2")
    Set colItems = objWMIService.ExecQuery("Select * from Win32_Service")
    For Each objItem in colItems
        Set objListItem  = objList.ListItems.Add
        objListItem.Text = objItem.Caption
        objListItem.ListSubItems.Add.Text = objItem.State
        objListItem.ListSubItems.Add.Text = objItem.Name
        objListItem.ListSubItems.Add.Text = objItem.Description
        objListItem.ListSubItems.Add.Text = objItem.StartMode
    Next
End Sub
 
Sub btn_start_onClick()
    strComputer = "."
    for n = 1 to list_servicenames.ListItems.Count
        if list_servicenames.ListItems(n).checked = True then
            strService = list_servicenames.ListItems(n).ListSubItems(2).Text
            Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
            Set colServiceList = objWMIService.ExecQuery ("Select * from Win32_Service where Name='" & strService & "'")
            For each objService in colServiceList
                errReturn = objService.StartService()
            Next
        end if
    next
    ListServices(strComputer)
End Sub
 
Sub btn_stop_onClick()
    strComputer = "."
    for n = 1 to list_servicenames.ListItems.Count
        if list_servicenames.ListItems(n).checked = True then
            strService = list_servicenames.ListItems(n).ListSubItems(2).Text
            Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
            Set colServiceList = objWMIService.ExecQuery ("Select * from Win32_Service where Name='" & strService & "'")
            For each objService in colServiceList
                errReturn = objService.StopService()
            Next
        end if
    next
    ListServices(strComputer)
End Sub
 
Sub btn_restart_onClick()
    strComputer = "."
    'Stop services
    for n = 1 to list_servicenames.ListItems.Count
        if list_servicenames.ListItems(n).checked = True then
            strService = list_servicenames.ListItems(n).ListSubItems(2).Text
            Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
            Set colServiceList = objWMIService.ExecQuery ("Select * from Win32_Service where Name='" & strService & "'")
            For each objService in colServiceList
                errReturn = objService.StopService()
            Next
        end if
    next
    'Start services
    for n = 1 to list_servicenames.ListItems.Count
        if list_servicenames.ListItems(n).checked = True then
            strService = list_servicenames.ListItems(n).ListSubItems(2).Text
            Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
            Set colServiceList = objWMIService.ExecQuery ("Select * from Win32_Service where Name='" & strService & "'")
            For each objService in colServiceList
                errReturn = objService.StartService()
            Next
        end if
    next
    ListServices(strComputer)
End Sub
 
Sub btn_Refresh_onClick()
    ListServices(".")
End Sub
 
Sub btn_exit_onClick()
    Window.Close
End Sub
 
function list_servicenames_ColumnClick(colheader)
    list_servicenames.SortKey = colheader.index-1
end function
 
</script>
 
<body>
 
<OBJECT id="list_servicenames" name="list_servicenames" classid="clsid:BDD1F04B-858B-11D1-B16A-00C0F0283628"></OBJECT>
<br />
<input type="button" value="Refresh" name="btn_Refresh" id="btn_Refresh" title="Click to refresh the services list"> &nbsp;
<input type="button" value="Start"   name="btn_start"   id="btn_start"   title="Click to Start the Services"> &nbsp;
<input type="button" value="Stop"    name="btn_stop"    id="btn_stop"    title="Click to Stop the Service"> &nbsp;
<input type="button" value="Restart" name="btn_restart" id="btn_restart" title="Click to Restart the Services"> &nbsp;
<input type="button" value="Exit"    name="btn_exit"    id="btn_exit"    title="Click to Exit Form ">
 
</body>

Open in new window

0
Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
Bill PrewCommented:
When you run this, do you get the list of services displayed?


»bp
0
 
Dennis DAuthor Commented:
No, it loads the HTA window in the background and launches the Windows Installer only.. I have to close mshta.exe and msiexec.exe in the task manager.  If I remove the CLSID from the object in the body section it will run, but return the error that's specified just after Sub Window_Onload in the script.  So I know it's a problem related to the CLSID, I just don't know what it could be.
0
 
Dennis DAuthor Commented:
This is what I see when I run that script
0
 
Bill PrewCommented:
Okay, thanks that's help me better understand what you have happening.

So that CLSID is an older ActiveX component that implements a listview control.  Many computers have it installed related to other applications installed, etc, I have it on Windows 10, but I'm a developer with a lot of apps installed.

Ideally it would be good to reduce / remove ActiveX dependencies from new HTAs , since that is sort of an old and declining technology.  It would be better to replace the listview with something purely in HTML, or a more contemporary approach.


»bp
0
 
Dennis DAuthor Commented:
I have that CLSID on my computer also.. I searched for it in the registry and it's there.  I guess I'll have to try and figure out a way to replace that, I just don't know what.. Thank you for looking into it, I appreciate it!
0
 
Bill PrewCommented:
Feels like with a little work a basic HTML table might be able to replace the listview control.  Maybe not quite as pretty, but perhaps functional enough.  Would have to play around with it.


»bp
0
 
Dennis DAuthor Commented:
Basically I'm replacing a script I wrote with just a batch file to control local servers I'm running on my machine.. anything will look better than DOS text scrolling I think.
0
 
Bill PrewCommented:
You have any javascript or jquery experience?  It might be possible to incorporate that into an HTA application and use one of the free open sourse grid "controls" built in javascript on jquery.


»bp
0
 
Dennis DAuthor Commented:
Not really no.  Right now I'm looking at powershell's ConvertTo-HTML command to convert that control.. Hopefully I'm on the right track but probably not.  I really have very little experience with all of this.  I'm just trying to learn and expand my capabilities.
0
 
Dennis DAuthor Commented:
Thank you very much Bill!  I was up all night rewriting my script.  I was having trouble figuring out how to get the data where I wanted in my table. The changes you made were exactly what I was looking for.  Now all I have to figure out is how to get the service name and service status for only 2 services.  Hopefully I can do that with what you wrote.  I really appreciate your time!
0
 
Bill PrewConnect With a Mentor Commented:
If you just want to view a few services you can do something like this in the ListServices subroutine:

Set colItems = objWMIService.ExecQuery("Select * From Win32_Service Where DisplayName = 'Plug and Play' Or DisplayName = 'Windows 

Open in new window



»bp
0
 
Dennis DAuthor Commented:
That's perfect!! Thank you again for all your help it's extremely appreciated!
0
 
Bill PrewCommented:
Great, glad I was of help, enjoyed working the issue with you, good luck.


»bp
0
 
Dennis DAuthor Commented:
I guess I was too hung up on the formatting aspect, I didn't check to see if it worked.  I thought I broke something but I couldn't get the code you wrote to work either.  The Refresh and Exit buttons work, but the Start, Stop, and Restart buttons don't.  I'll post my altered code in here.  Maybe someone can tell me what's wrong with the start, stop, and restart buttons please.

<head>
<title>Server Services</title>
<HTA:APPLICATION 
     APPLICATIONNAME="Server Services"
     BORDER="thin"
     SCROLL="no"
	 MinimizeButton="no"
	 MaximizeButton="no"
     SINGLEINSTANCE="yes"
     ID="oHTA"
>
 <APPLICATION:HTA>
</head>

<style>
body {
    background-color: black;
    font-family: 'Source Sans Pro', sans-serif;
    font-size: 25px;
}
table {
	width: 100%;
	border-color: firebrick;
    background-color: black;
	color: khaki;
    font-family: 'Source Sans Pro', sans-serif;
    font-size: 12px;
}
th {
	border-color: firebrick;
    background-color: black;
	color: khaki;
}
td {
	border-color: firebrick;
}

</style>

<script language="VBScript">

Sub Resize()
	Window.ResizeTo 380,200
End Sub
 
Sub Window_OnLoad
    ' Populate table with list of services
	Window.ResizeTo 380,200
    ListServices(".")
End Sub
 
Sub ListServices(sComputer)
    Set oTable = Document.All("list_servicenames")

    ' Delete any existing data rows
    rowCount = oTable.Rows.Length
    If rowCount > 1 Then
        For i = rowCount - 1 To 1 Step -1
            oTable.DeleteRow(i)
        Next
    End If

    ON ERROR RESUME NEXT

    ' Get all services from WMI
    set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & sComputer & "\root\cimv2")
	Set colItems = objWMIService.ExecQuery("Select * From Win32_Service Where DisplayName = 'Performance Issues' Or DisplayName = 'Spaced Out'")
	
    ' For each services add a data row to the table
    For Each objItem in colItems
        Set TR = oTable.InsertRow()
        Set TD = TR.InsertCell()
        TD.InnerHTML = "<input type=""checkbox""></td>"
        Set TD = TR.InsertCell()
        TD.InnerHTML = objItem.Name
        Set TD = TR.InsertCell()
        TD.InnerHTML = objItem.State

    Next
End Sub
 
Sub btn_start_onClick()

    strComputer = "."                                                                                                   
    Set oTable = Document.All("list_servicenames")
    rowCount = oTable.Rows.Length

    ' Process all selected rows of table, Start service
    For i = 1 To rowCount - 1 Step 1
        If UCase(Left(oTable.Rows(i).Cells(0).InnerHTML, 14)) = "<INPUT CHECKED" Then
            strService = oTable.Rows(i).Cells(1).InnerHTML
            Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2") 
            Set colServiceList = objWMIService.ExecQuery ("Select * from Win32_Service where Name='" & strService & "'")
            For each objService in colServiceList                                                                       
                errReturn = objService.StartService()                                                                   
            Next                                                                                                        
        End If                                                                                                          
    Next                                                                                                                

    ' Refresh Service table
    ListServices(strComputer)                                                                                           

End Sub
 
Sub btn_stop_onClick()

    strComputer = "."                                                                                                   
    Set oTable = Document.All("list_servicenames")
    rowCount = oTable.Rows.Length

    ' Process all selected rows of table, Stop service
    For i = 1 To rowCount - 1 Step 1
        If UCase(Left(oTable.Rows(i).Cells(0).InnerHTML, 14)) = "<INPUT CHECKED" Then
            strService = oTable.Rows(i).Cells(1).InnerHTML
            Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2") 
            Set colServiceList = objWMIService.ExecQuery ("Select * from Win32_Service where Name='" & strService & "'")
            For each objService in colServiceList                                                                       
                errReturn = objService.StopService()                                                                    
            Next                                                                                                        
        End If                                                                                                          
    Next                                                                                                                
    ListServices(strComputer)                                                                                           

End Sub
 
Sub btn_restart_onClick()

    strComputer = "."                                                                                                   
    Set oTable = Document.All("list_servicenames")
    rowCount = oTable.Rows.Length

    ' Process all selected rows of table, Stop service
    For i = 1 To rowCount - 1 Step 1
        If UCase(Left(oTable.Rows(i).Cells(0).InnerHTML, 14)) = "<INPUT CHECKED" Then
            strService = oTable.Rows(i).Cells(1).InnerHTML
            Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2") 
            Set colServiceList = objWMIService.ExecQuery ("Select * from Win32_Service where Name='" & strService & "'")
            For each objService in colServiceList                                                                       
                errReturn = objService.StopService()                                                                    
            Next                                                                                                        
        End If                                                                                                          
    Next                                                                                                                

    ' Process all selected rows of table, Start service
    For i = 1 To rowCount - 1 Step 1
        If UCase(Left(oTable.Rows(i).Cells(0).InnerHTML, 14)) = "<INPUT CHECKED" Then
            strService = oTable.Rows(i).Cells(1).InnerHTML
            Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2") 
            Set colServiceList = objWMIService.ExecQuery ("Select * from Win32_Service where Name='" & strService & "'")
            For each objService in colServiceList                                                                       
                errReturn = objService.StartService()                                                                   
            Next                                                                                                        
        End If                                                                                                          
    Next                                                                                                                
    ListServices(strComputer)                                                                                           
End Sub                                                                                                                 
 
Sub btn_Refresh_onClick()
    ListServices(".")
End Sub
 
Sub btn_exit_onClick()
    Window.Close
End Sub
 
</script>
 
<body>

<table border=1 id=list_servicenames> 
<col align="center">
<col align="left">
<col align="center">
<tr> 
<th align="center">Select</td>
<th align="center">Name</td>
<th align="center">State</td>
</tr> 
</table> 

 
<br />
<input type="button" value="Refresh" name="btn_Refresh" id="btn_Refresh" title="Click to refresh the services list"> &nbsp;
<input type="button" value="Start"   name="btn_start"   id="btn_start"   title="Click to Start the Services"> &nbsp;
<input type="button" value="Stop"    name="btn_stop"    id="btn_stop"    title="Click to Stop the Service"> &nbsp;
<input type="button" value="Restart" name="btn_restart" id="btn_restart" title="Click to Restart the Services"> &nbsp;
<input type="button" value="Exit"    name="btn_exit"    id="btn_exit"    title="Click to Exit Form ">
 
</body>

Open in new window

0
 
Bill PrewCommented:
For future reference, this question continues on at:



»bp
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.