Finding Services Using non-System accounts

Originally published March 23, 2006

 

I went into a new customer recently and found that they had about a gazillion standalone servers, all of which had the same administrator password, and they used the Administrator account to run some services.

While there often seem to be good reasons for doing this (pass through authentication, only requiring a single account having elevated privileges, etc.) it almost always turns out to be a bad idea. It makes it difficult to change passwords when employees turn over, and you can have service failures when you change passwords.

And, lest you forget, there are other things that could possibly depend on these passwords too: COM objects and websites, to mention two other possibilities.

So, I wrote a script that, based upon a simple input file containing a list of computers, goes out and checks for all services running on each computer that are using a non-default account. For the purposes of my script, I considered these accounts to be default accounts: "NT AUTHORITY\LocalService", "LocalSystem",   ".\ASPNET",  "NT AUTHORITY\NETWORK SERVICE",  "NT AUTHORITY\NetworkService". In your environment, those will probably work, but I make no guarantees for that. :-)

This script also specifically identifies the total number of services running under the administrator account. Those are things you really probably want to change!

The input file is easy to generate from adfind/dsquery/dns - whatever way you can use to produce a list of servers in your environment, one server per line. If you need to have comment lines, then begin a line with the crosshatch character (”#”).

Sample summary output:

Processing complete
Total computers processed: 33
Total Administrator services: 27
Total special services: 62
Total errors: 0
Total comment lines: 0

Of course, as always, this script is provided “AS IS” and conveys no warranties.

Option Explicit
' check-services.vbs

Const ForReading = 1

Dim objFS, objFileIn, iCount, iError, iComment, iAdminCount, iTot
Dim strRemoteComputer

Sub e (str)
 WScript.Echo str
End Sub

Function ErrorReport (str)
 If Err.Number Then
  iError = iError + 1
  ErrorReport = True
  e "Error 0x" & CStr (Hex (Err.Number)) & " occurred " & str
  If Err.Description <> "" Then
                 e "Error description: " & Err.Description & "."
  End If
  Err.Clear
 Else
  ErrorReport = False
 End If
End Function

Sub Startup
 If Wscript.Arguments.Count <> 1 Then
  e "Usage: Check-Services.vbs listofcomputers.txt"
  e " "
  e "'listofcomputers.txt' contains a list of the computers"
  e "that will be checked for services that do not contain"
  e "default accounts."
  e " "
  wscript.quit 1
 End If

 On Error Resume Next

 Set objFS = CreateObject ("Scripting.FileSystemObject")
 If ErrorReport ("while creating Scripting.FileSystemObject") Then
  wscript.quit 1
 End If

 Set objFileIn = objFS.OpenTextFile (wscript.arguments (0), ForReading)
 If ErrorReport ("while opening " & wscript.arguments (0)) Then
  Set objFS = Nothing
  wscript.quit 1
 End If

 iTot = 0
 iCount = 0
 iError = 0
 iComment = 0
 iAdminCount = 0
End Sub

Sub Shutdown
 objFileIn.Close
 Set objFileIn = Nothing

 Set objFS = Nothing
End Sub

' Constants we need for WBEM calls
Const wbemFlagReturnImmediately = &H10
Const wbemFlagForwardOnly       = &H20

Dim arrExclude

arrExclude = Array ("NT AUTHORITY\LocalService", _
      "LocalSystem", _
      ".\ASPNET", _
      "NT AUTHORITY\NETWORK SERVICE", _
      "NT AUTHORITY\NetworkService")

Function CheckExclusions (ByVal strVal)
 Dim i

 For i = LBound (arrExclude) To UBound (arrExclude)
  If LCase (strVal) = LCase (arrExclude (i)) Then
   CheckExclusions = True
   Exit Function
  End If
 Next

 CheckExclusions = False
End Function
     
Sub CheckServicesOnComputer (ByVal strComputer)
 Dim objWMIService
 Dim colItems, objItem
 Dim iExcluded, iIncluded

 iExcluded = 0
 iIncluded = 0

 WScript.Echo ""
 WScript.Echo "Checking computer " & strComputer

 On Error Resume Next
 Set objWMIService = GetObject ("winmgmts:\\" & strComputer & "\root\CIMV2")
 If ErrorReport ("opening CIMv2") Then Exit Sub
 Set colItems = objWMIService.ExecQuery ("SELECT name,startname,caption FROM Win32_Service", "WQL", _
  wbemFlagReturnImmediately + wbemFlagForwardOnly)
 If ErrorReport ("on ExecQuery") Then Exit Sub
 On Error Goto 0

 ' if we get any items returned, it's installed
 For Each objItem In colItems
  If CheckExclusions (objItem.StartName) Then
   iExcluded = iExcluded + 1
  Else
   iIncluded = iIncluded + 1
   If Right (LCase (objItem.StartName), Len ("\Administrator")) = "\administrator" Then iAdminCount = iAdminCount + 1
   'wscript.echo "name = " & objItem.Name & " startname = " & objItem.StartName & " caption = " & objItem.Caption
   e " startname = " & objItem.StartName & " caption = " & objItem.Caption
  End If
 Next

 Set colItems = Nothing
 Set objWMIService = Nothing

 Wscript.echo "Included items = " & iIncluded & " excluded items = " & iExcluded & " for computer " & strComputer
 iTot = iTot + iIncluded
End Sub

 ' Main

 Call Startup
 Do Until objFileIn.AtEndOfStream
  strRemoteComputer = objFileIn.ReadLine
  If ErrorReport ("while reading input line") Then
   Exit Do
  End If

  ' If the first character is a "#", then the line is a comment
  If Left (strRemoteComputer, 1) <> "#" Then
   Call CheckServicesOnComputer (strRemoteComputer)
   iCount = iCount + 1
  Else
   iComment = iComment + 1
  End If
 Loop

 Call Shutdown

 e " "
 e "Processing complete"
 e "Total computers processed: " & iCount
 e "Total Administrator services: " & iAdminCount
 e "Total special services: " & iTot
 e "Total errors: " & iError
 e "Total comment lines: " & iComment

Published Tuesday, November 13, 2007 8:27 PM by michael
Filed under: ,

Comments

Friday, February 29, 2008 8:32 AM by Michael's meanderings...

# Finding Services Using non-System Accounts With PowerShell

In March of 2006, I authored this blog post, Finding Services Using non-System Accounts , with the script

Friday, June 20, 2008 9:42 AM by Michael's meanderings...

# stealing my work....grrrr....

I was recently (ok, this morning) trying to find out about a vbscript (actually WMI) error that I was