Link to home
Start Free TrialLog in
Avatar of Thor2923
Thor2923Flag for United States of America

asked on

I need to I identify which servers on my network have services dependent on our DOMAIN ADMIN account

We are in the process of changing our DOMAIN ADMIN password. We are concerned that there are service running that are dependent on it as other engineers set this network up. Does anyone know of a way, other then going from machine to machine and clicking on each service, to see which services on which servers are dependent on the DOMAIN ADMIN login and have the password hardcoded in the SERVICES area?
Avatar of Darius Ghassem
Darius Ghassem
Flag of United States of America image

Really not a way to tell of there are certain user accounts attached to a service without actually looking at the services themselves. The best practice is to create an account that is not associated with any other purpose then attach this user account to the services that need access.

Domain Admin account should only be used for Domain functions.

From a server you can go to computer manage then right-click the server name then you can connect to each server from here to check  the services to see if Domain Admin account is attached.

Check this out as well

http://msdn.microsoft.com/en-us/library/windows/desktop/ms686005(v=vs.85).aspx 
Here is a script that I put together to query all my domain servers and return the services that are running via a domain account.
Note: When querying the service you is it a Domain account that is running it.  If so you can user the Like %domainName% as a search criteria.

This script access your AD and loops through an OU that contains your Servers.  Pings each one to see if they are available to querying. Quieries the Services for any serviec running with an account Like Domain Name and then outputs.

Open Notepad and save it as a vbs  then run it from a command prompt cscript <file.vbs>.


Good luck and if  you have any questions post.



on error resume next
Const adOpenStatic = 3
Const adLockOptimistic = 3
Const adUseClient = 3
Const adStateOpen = 1

Set objConnection = CreateObject("ADODB.Connection")
Set objRecordset = CreateObject("ADODB.Recordset")

Dim StrComputerName, StrUser
Dim objConn 'ADO Connection object
Dim objRS 'ADO Recordset object

'************************************************************************************
'Connecting to Active Directory														*
'************************************************************************************
objConnection.Provider = "ADSDSOObject"
objConnection.Open "","CN=Administrator,OU=IT Staff,DC=DomainName,DC=local", "password"

If objConnection.State = adStateOpen Then
'WScript.Echo "Authentication Successful!"
Else
'WScript.Echo "Authentication Failed."

WScript.Quit(1)
End If

StrADSPATH = "OU=Servers,DC=DomainName,DC=local" 
Set objRS = objConnection.Execute("<LDAP://" & StrADSPATH & ">;(&(objectCategory=computer)(objectClass=user));Name,ADsPath,altRecipient;SubTree")
While Not objRS.EOF
strName = objRS.Fields.Item("Name").Value
strADs = objRS.Fields.Item("ADsPath").Value
	blnPing = PingHost
  If blnPing = True Then





'************************************************************************************
'Data Collection																	*
'************************************************************************************
wscript.echo strName 
Set objWMIService = GetObject("winmgmts:" _
    & "{impersonationLevel=impersonate}!\\" _
    & strName & "\root\cimv2")
Set colServices = objWMIService.ExecQuery _
    ("Select * from Win32_Service Where StartName like '%DomainName%'") 'Note Change Value to a username that is running the service. 
For Each objService in colServices
    Wscript.Echo vbtab & objService.DisplayName 
Next
								
end if

objRS.MoveNext
			 Wend
	set objRS = Nothing
	objConnection.Close

'********************************************
'Pings the server to see if it's available  *
'******************************************** 

Function PingHost

Set objShell = CreateObject("WScript.Shell")
Set objExec = objShell.Exec("ping -n 2 -w 1000 " & strName)
strPingResults = LCase(objExec.StdOut.ReadAll)
If InStr(strPingResults, "reply from") Then
  	PingHost = True
Else
	PingHost = False
End If

End Function

Open in new window

Avatar of Thor2923

ASKER

wow that is quite an interesting script....I am not really a vbs person, but will certainly check it out
Do I run this on each individual server? I will start with a test server to make sure I understand how it all works
No you do not have to run this on each computer.
what is your actual goal?
Query All Servers running a service as a Domain User?
If yes, are all your servers under one OU collection in AD?
I need to tweak the script.
It is not working as I expected.
Hold off for the time being.

Mike
Here is a script that I just confirms worked.

The query goes by OU and all sub-OU's under it.  If you run this at the top level (DC=DOMAIN,DC=LOCAL) this will query every computer in your Domain and return the name of the computer as well as the services that are running by a domain user.

I can modify it so it will query your entire Domain, but only return machines running on OS of WIndows Server XXXX.

Note:
Where ever you see DC=Change to your Domain Name change it to your name (i.e. DC=Contoso,DC=Local or it could be DC=Contoso,DC=com)
This should work nicely.
on error resume next
Const adOpenStatic = 3
Const adLockOptimistic = 3
Const adUseClient = 3
Const adStateOpen = 1

Const ADS_PROPERTY_CLEAR = 1
Const ADS_PROPERTY_UPDATE = 2
Const ADS_PROPERTY_APPEND = 3
Const ADS_PROPERTY_DELETE = 4
Set objConnection = CreateObject("ADODB.Connection")
Set objRecordset = CreateObject("ADODB.Recordset")

Dim StrComputerName, StrUser, strManufacturer, StrModel, StrSN, StrDiskLetter, strCpu, strProcessors, strComputersystem
Dim StrMemory 'as interger
Dim objConn 'ADO Connection object
Dim objRS 'ADO Recordset object

'************************************************************************************
'Connecting to Active Directory														*
'************************************************************************************
objConnection.Provider = "ADSDSOObject"
objConnection.Open "","CN=Administrator,OU=IT Staff,DC=Change to your Domain Name,DC=local", "fr1ckbl0m"

If objConnection.State = adStateOpen Then
'WScript.Echo "Authentication Successful!"
Else
'WScript.Echo "Authentication Failed."

WScript.Quit(1)
End If

StrADSPATH = "OU=Servers,OU=All computers,DC=Change to your Domain Name,DC=local"
Set objRS = objConnection.Execute("<LDAP://" & StrADSPATH & ">;(&(objectCategory=computer)(objectClass=user));Name,ADsPath,operatingSystem;SubTree")
While Not objRS.EOF
strAlt = objRS.Fields.Item("operatingSystem").Value
strName = objRS.Fields.Item("Name").Value
strADs = objRS.Fields.Item("ADsPath").Value
'	blnPing = PingHost
  'If blnPing = True Then





'************************************************************************************
'Data Collection																	*
'************************************************************************************
wscript.echo strName & VBTAB & StrAlt
Set objWMIService = GetObject("winmgmts:" _
    & "{impersonationLevel=impersonate}!\\" _
    & strName & "\root\cimv2")
Set colServices = objWMIService.ExecQuery _
    ("Select * from Win32_Service Where StartName like '%Change to your Domain Name%'")
For Each objService in colServices
    Wscript.Echo vbtab & objService.DisplayName 
Next
								
'end if

objRS.MoveNext
			 Wend
	set objRS = Nothing
	objConnection.Close


'********************************************
'Pings the server to see if it's available  *
'******************************************** 

Function PingHost

Set objShell = CreateObject("WScript.Shell")
Set objExec = objShell.Exec("ping -n 2 -w 1000 " & strName)
strPingResults = LCase(objExec.StdOut.ReadAll)
If InStr(strPingResults, "reply from") Then
  PingHost = True
Else
	PingHost = False
End If

End Function

Open in new window

I have modified the script to reduce the number of adjustments you would need to make to the script so it works for your environment.
Here is a script that will work really nice.

Make sure you run the script with a user that has the proper security rights to read AD.
1: Copy script to Notepad and save as VBS ext.
2: Launch Command Prompt as a Domain Administrator (if you are one then no worries)
3: Type: cscript "Path of the VBS"  
4: To write to a file type cscript "Path of the VBS"  > "Path".txt.
5: Import into excel and separate by Tab

on error resume next
Const adOpenStatic = 3
Const adLockOptimistic = 3
Const adUseClient = 3
Const adStateOpen = 1

Const ADS_PROPERTY_CLEAR = 1
Const ADS_PROPERTY_UPDATE = 2
Const ADS_PROPERTY_APPEND = 3
Const ADS_PROPERTY_DELETE = 4
Set objConnection = CreateObject("ADODB.Connection")
Set objRecordset = CreateObject("ADODB.Recordset")

Dim StrComputerName, StrUser
Dim StrMemory 'as interger
Dim objConn 'ADO Connection object
Dim objRS 'ADO Recordset object

'************************************************************************************
'Connecting to Active Directory														*
'************************************************************************************
objConnection.Provider = "ADSDSOObject"
objConnection.Open "" 
If objConnection.State = adStateOpen Then
'WScript.Echo "Authentication Successful!"
Else
'WScript.Echo "Authentication Failed."

WScript.Quit(1)
End If

'Get the Root DSE from a random DC
Set objRootDSE = GetObject("LDAP://RootDSE")

'Connect to the schema container on a random DC
strDNSDomain = objRootDSE.Get("defaultNamingContext")
Set StrDC = GetObject("LDAP://" & StrDNSDomain)
'wscript.echo StrDC.DC 
Set objRS = objConnection.Execute("<LDAP://" & strDNSDomain & ">;(&(objectCategory=computer)(objectClass=user));Name,ADsPath,operatingSystem;SubTree")
While Not objRS.EOF
strAlt = objRS.Fields.Item("operatingSystem").Value
strName = objRS.Fields.Item("Name").Value
strADs = objRS.Fields.Item("ADsPath").Value


'************************************************************************************
'Data Collection															
'************************************************************************************

If instr(strAlt,"Server") then
	blnping = PingHost
If blnping = true then
Set objWMIService = GetObject("winmgmts:" _
    & "{impersonationLevel=impersonate}!\\" _
    & strName & "\root\cimv2")
Set colServices = objWMIService.ExecQuery _
    ("Select * from Win32_Service Where StartName like '%' & StrDC & '%'")
wscript.echo strName & VBTAB & StrAlt
For Each objService in colServices 
   
Wscript.Echo vbtab & objService.DisplayName & vbtab & objservice.startname
Next
	End if
End IF								


objRS.MoveNext
			 Wend
	set objRS = Nothing
	objConnection.Close



'********************************************
'Pings the server to see if it's available  *
'******************************************** 

Function PingHost

Set objShell = CreateObject("WScript.Shell")
Set objExec = objShell.Exec("ping -n 2 -w 1000 " & strName)
strPingResults = LCase(objExec.StdOut.ReadAll)
If InStr(strPingResults, "reply from") Then
  PingHost = True
Else
	PingHost = False
End If

End Function

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of yo_bee
yo_bee
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thanks, wonderful script
Glad it worked.
You forced me to streamline this a bit, but it was well worth it for both of us.
We have 100 servers. How can I modify the script to log it in a csv format?
Really cool by the way!
Remark line 59 with a ' before wscript

Replace line 62 with
 Wscript.Echo strname & "," & objService.DisplayName & "," & objservice.
Run Cmd

Cscript filename.vbs > c:\output.csv
Just noticed the previous post about the replacement instructions is missing .startname at the end.
I could write it so it writes to a csv and output , but that is just extra work. I rather just use > c:\filename.csv or .txt.

Any other questions just post
Thanks a lot. It did return services running under different users as well as for the Administrator account. I expected to see more services running as Administrator as well. Is there anything that would keep this script from being run against any of our windows server within our domain? We have a mixed environment...Windows Server 2003 and 2008

Thanks again for this!
Should not.
I would recommend running Cmd with elevated privlages. Domain admin account prefefred.  
The process uses WMI connections so if your run the Cmd as some high level domain admin all should work.
I have a mix environment and I am able to successfully run the queries.

I will confirm tomorrow.
I am a domain admin but I will play with it to see if I can achieve different results. Thank you
I would still run cmd as the actual administrator account or at least run as administrator.
Here is the modified script for CSV

Yes it works on both 2003 and 2008 boxes.
I an running it from my W7 machine as a domain admin
1: Command Prompt (As Administrator)
2: cscript "c:\scripts\VBS FILES\Server_Services_List.vbs" > c:\ServiceOutput.csv
3: Open in Excel.

 
on error resume next
Const adOpenStatic = 3
Const adLockOptimistic = 3
Const adUseClient = 3
Const adStateOpen = 1

Const ADS_PROPERTY_CLEAR = 1
Const ADS_PROPERTY_UPDATE = 2
Const ADS_PROPERTY_APPEND = 3
Const ADS_PROPERTY_DELETE = 4
Set objConnection = CreateObject("ADODB.Connection")
Set objRecordset = CreateObject("ADODB.Recordset")

Dim StrComputerName, StrUser
Dim StrMemory 'as interger
Dim objConn 'ADO Connection object
Dim objRS 'ADO Recordset object

'************************************************************************************
'Connecting to Active Directory														*
'************************************************************************************
objConnection.Provider = "ADSDSOObject"
objConnection.Open "" 
If objConnection.State = adStateOpen Then
'WScript.Echo "Authentication Successful!"
Else
'WScript.Echo "Authentication Failed."

WScript.Quit(1)
End If

'Get the Root DSE from a random DC
Set objRootDSE = GetObject("LDAP://RootDSE")

'Connect to the schema container on a random DC
strDNSDomain = objRootDSE.Get("defaultNamingContext")
Set StrDC = GetObject("LDAP://" & StrDNSDomain)
StrServices = Ucase(StrDC.DC)
wscript.echo StrServices
wscript.echo "Server Name,Service,User Name" 
Set objRS = objConnection.Execute("<LDAP://" & strDNSDomain & ">;(&(objectCategory=computer)(objectClass=user));Name,ADsPath,operatingSystem;SubTree")
While Not objRS.EOF
strAlt = objRS.Fields.Item("operatingSystem").Value
strName = objRS.Fields.Item("Name").Value
strADs = objRS.Fields.Item("ADsPath").Value


'************************************************************************************
'Data Collection																	*
'************************************************************************************

If instr(strAlt,"Server") then
	blnping = PingHost
If blnping = true then
Set objWMIService = GetObject("winmgmts:" _
    & "{impersonationLevel=impersonate}!\\" _
    & strName & "\root\cimv2")
Set colServices = objWMIService.ExecQuery _
    ("Select * from Win32_Service Where StartName like '%" & StrServices & "%'" )

For Each objService in colServices 
   
Wscript.Echo StrName & "," & objService.DisplayName & "," & objservice.startname
Next
	End if
End IF								


objRS.MoveNext
			 Wend
	set objRS = Nothing
	objConnection.Close



'********************************************
'Pings the server to see if it's available  *
'******************************************** 

Function PingHost

Set objShell = CreateObject("WScript.Shell")
Set objExec = objShell.Exec("ping -n 2 -w 1000 " & strName)
strPingResults = LCase(objExec.StdOut.ReadAll)
If InStr(strPingResults, "reply from") Then
  PingHost = True
Else
	PingHost = False
End If

End Function

Open in new window

Much thanks MK.
I guess you can see the major changes that I made from the first script to the last one.

When I first constructed that script I just started playing around with ADSI and VBS.
I have have learned much to stream line this for domains without needing the domain info added to the script.