Wednesday, June 18, 2008

VBScript to get Services from Servers

The script below was written to parse a selected text file containing server names, loop through the list, create a new worksheet for each server and put the services into that worksheet. This can be done for as many servers as needed. At the end of the routine, the script saves the Excel file to the user's desktop and closes the application. I have run it several times and it has worked without fail so far. This is a nice script to gather all of the relevant service information for all of the computers in an environment. This information can be invaluable during recovery of a system.


'*********************************************************************************
'Script to remotely inventory installed services from a list of machines from a
' text file, put the services into an Excel workbook, and then save the
' workbook to the desktop.
' Created by: Brian Bohanon
' Created: 6/17/2008
'*********************************************************************************

Option Explicit

Dim arrFileLines()
Dim tst
Dim i, j, k, l
Dim objFSO, objFile, objDialog, objExcel, objWMIService, objService, objWorkbook
Dim WshShell
Dim colServices
Dim srcFileName 'source file
Dim intResult
Dim strComputer 'computer to inventory

'Constants
Const xlLeft = -4131
Const xlHorizontal = -4128

'Set Objects
Set objExcel = CreateObject("Excel.Application")
Set objDialog = CreateObject("UserAccounts.CommonDialog")
Set WshShell = WScript.CreateObject("WScript.Shell")

'Open the source file that contains the list of computers
objDialog.Filter = "Text Files|*.txt"
objDialog.InitialDir = WshShell.SpecialFolders("Desktop")
intResult = objDialog.ShowOpen

If intResult = 0 Then
Wscript.Quit
Else
'Set selected file to srcFileName
srcFileName = objDialog.FileName

i = 0
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile(srcFileName, 1)
Do Until objFile.AtEndOfStream
Redim Preserve arrFileLines(i)
arrFileLines(i) = objFile.ReadLine
i = i + 1
Loop
objFile.Close

'*********************************************************************************
' Create a new Excel Workboot
'*********************************************************************************
objExcel.Visible = True
Set objWorkbook = objExcel.Workbooks.Add()

'*********************************************************************************
'Loop through the array of computers, create a worksheet with the computer name,
' get the list of services,
' and write out the services to the excel sheet
'*********************************************************************************

k = 3
objExcel.Worksheets("Sheet1").Delete
objExcel.Worksheets("Sheet2").Delete

For l = Ubound(arrFileLines) to LBound(arrFileLines) Step -1
On Error Resume Next
if k = 3 then
objExcel.Worksheets("Sheet" & k).Activate
objExcel.Worksheets("Sheet" & k).Name = arrFileLines(l)
else
objExcel.Worksheets.Add
objExcel.Worksheets("Sheet" & k).Activate
objExcel.Worksheets("Sheet" & k).Name = arrFileLines(l)
end if

'*********************************************************************************
'Services Information
'*********************************************************************************

'Select server to inventory
Set objWMIService = GetObject("winmgmts:\\" & arrFileLines(l) & "\root\cimv2")
Set colServices = objWMIService.ExecQuery("Select * From Win32_Service")

i = 1
j = 1

'Column headers
objExcel.Cells(i, j).Value = "Service"
objExcel.Cells(i, j).Font.Bold = TRUE
j = j + 1
objExcel.Cells(i, j).Value = "Status"
objExcel.Cells(i, j).Font.Bold = TRUE
j = j + 1
objExcel.Cells(i, j).Value = "Start Mode"
objExcel.Cells(i, j).Font.Bold = TRUE
j = j + 1
objExcel.Cells(i, j).Value = "Start Name"
objExcel.Cells(i, j).Font.Bold = TRUE
j = j + 1
objExcel.Cells(i, j).Value = "Path Name"
objExcel.Cells(i, j).Font.Bold = TRUE

'Services data
For Each objService in colServices
i = i + 1
j = 1
objExcel.Cells(i, j) = objService.Name
j = j + 1
objExcel.Cells(i, j) = objService.State
'Show stopped services in Red
If objService.State = "Stopped" Then
objExcel.Cells(i, j).Font.ColorIndex = 3
End If
j = j + 1
objExcel.Cells(i, j) = objService.StartMode
j = j + 1
objExcel.Cells(i, j) = objService.StartName
j = j + 1
objExcel.Cells(i, j) = objService.PathName
Next

' Autofit the first column to fit the longest service name
objExcel.Columns("A:Z").EntireColumn.AutoFit
objExcel.Columns("A:Z").HorizontalAlignment = xlLeft

k = k + 1
Next

'Save the workbook to the desktop
objWorkbook.SaveAs(WshShell.SpecialFolders("Desktop") & "\ServerServices_" & Month(Date()) & "_" & Day(Date()) & "_" & Year(Date()) & ".xls")

'Close Excel
objExcel.Quit

End If

'*********************************************************************************
'Cleanup
'*********************************************************************************

'Cleanup objects

Set objExcel = nothing
Set objFSO = nothing
Set objWMIService = nothing
Set objService = nothing
Set objFile = nothing
Set objDialog = nothing
Set WshShell = nothing

'Inform the user that the process is complete
Wscript.Echo("Finished")

Wscript.Quit 0

6 comments:

Bala said...

This Script is for Windows Platform. Is there any script for Unix/Linux platform....

Brian Bohanon said...

Bala,
The quick and dirty for this would be to use Cygwin+SSH from your workstation like so...

ssh root@server 'chkconfig --list' >> server_name.txt

Then you could import that (or use a macro to import it) into Excel. To further this, you could create a directory that you dump all of your services in and have Excel import/refresh the data each time you open your workbook.

I will put a new post up shortly for bash/cygwin that will connect to the RedHat/CentOS servers and export the services to text files. Then you can use Excel as described above.

Thanks for reading.

Brian Bohanon said...

Bala,
Sorry but I won't be able to get to this completely today and you probably need it now. Tools: Cygwin, text file with the server names, Excel. Run the following from a bash prompt and you will get a text file for each server that contains their services.

for i in `cat Servers.txt `;
do ssh root@$i "chkconfig --list" >> $i.txt;
done


Additionally, you could use SSH keys to eliminate the need to enter a password for each server.

Special thanks to Jason for "uncomplicating" my script!

bhaskar said...

HI iam able to run the script but in the output its not showing any services only excel file is opening thats it.Please say me how to proceed i want this script very very urgently as i need to dialy 4 times for a list of around 50-60 servers.Please iam waiting for reply and my id is vsiva25@gmail.com.

arptro said...

I would love to use this script but I receive the following error:

C:\Scripts\computerinventory.vbs(27, 1) Microsoft VBScript runtime error: Active
X component can't create object: 'UserAccounts.CommonDialog'

Thanks

Brian Bohanon said...

@arptro - this script is somewhat depricated. Microsoft (as of Vista) no longer uses the UserAccounts.CommonDialog. I would recommend trying to get this information using PowerShell. A quick way to get this with PowerShell would be:
get-service -computername (get-content computers.txt) | select MachineName,DisplayName, Status | export-csv filename.csv

Place the computer names you want to query in the computers.txt file.

You could do this with PowerShell and WMI (see The Scripting Guy's post on this method here: http://blogs.technet.com/b/heyscriptingguy/archive/2012/02/15/the-scripting-wife-uses-powershell-to-find-service-accounts.aspx)
gwmi win32_service -computername (get-content computers.txt) | select SystemName, DisplayName, State, StartName