Solved

Active Directory Query for server information

Posted on 2009-07-09
15
503 Views
Last Modified: 2013-12-24
What would be the best way to gather info about 400+ servers: such as name\IP, OS and specific services running?  I have an XLS doc and would like to run a query for the batch of servers on my list, then output the results to either a text file or XLS doc.
Anyone have any ideas?  
0
Comment
Question by:wnbtechnology
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
15 Comments
 
LVL 5

Expert Comment

by:wpathan
ID: 24820501
netscan.exe or angry ip scanner is a good one if you have a range of ips to scan but again both of them are not capable of gathering services info, hence i suggest you use some specialized software like a vulnerability assessment tool which can provide you an exhaustive info, also you can provide hostnames/ips to these tools via an external source like a text file.
Hope this helps.
0
 
LVL 20

Expert Comment

by:EndureKona
ID: 24820516
In the past I used a produce called Fastlane Reporter from Quest.     It worked well, now it appears the name has been shortened to Reporter

http://www.quest.com/reporter/
0
 
LVL 27

Expert Comment

by:bluntTony
ID: 24823405
Hi there, you could script relatively easily using VBScript if you don't want to pay for anything. Exactly what info do you want, and how do you envisage it being displayed?

It's quite easy to get Name, IP, OS and running services via WMI remotely, but how would you like this displayed? If you've got a list of 400 servers, and each server's got 60+ services running, how do you want it showing? All sixty services listed off in one cell?

Let us know and I'll knock a script up if you're interested.
0
Webinar: MongoDB® Index Types

Join Percona’s Senior Technical Services Engineer, Adamo Tonete as he presents “MongoDB Index Types, How, When and Where Should They be Used?” on Wednesday, July 12, 2017 at 11:00 am PDT / 2:00 pm EDT (UTC-7).

 
LVL 41

Expert Comment

by:graye
ID: 24840393
I've got a program that will what you want (plus a gallizon other things)...  it's called Son Of Snoop on Steroids (SOSOS) and is available here:
http://www.sosos.emmet-gray.com/ 
It is also available as VB.Net source code with no licensing restrictions at all...  so if you've got a programmer handy, you're free to modify / plagiarize as you see fit
0
 

Author Comment

by:wnbtechnology
ID: 24857510
All of you have some great tools!!  I definitely cannot run a scanner againts our production server subnets, our communication department would go nuts!  Though I can run an LDAP query VBscript on our domain controllers in Active Directory. :)

bluntTony,

I would only need to display one service, which is "OpsMgr Health Service".  
I'd like to out the scan to either a .CSV, .TXT, or .XLS file it at all possible.

-One row per server
Column 1 = Server Name
Column 2 = IP Address
Column 3 = OS
Column 4 = Ping Status

Basically I'm doing a discovery of all of our production servers for my inventory in our System Center Operations Manager (SCOM).  SCOM can discover, when it's given an IP range to scan, but I would like gather my own information to verify.

Thanks for all the help!!
0
 

Author Comment

by:wnbtechnology
ID: 24857549
graye,

I'm going to recommend the Quest Reporter to my IT Infrastructure team as well!  Seems like a valuable tool to have, considering that our server farms are growing fast!

Thanks!
0
 

Author Comment

by:wnbtechnology
ID: 24857573
My apologies, that was EndureKona. :)
Also, when you got the Quest Reporter, how much was it for you?
0
 
LVL 27

Expert Comment

by:bluntTony
ID: 24858551
Hi there, below is a script which will do as you asked. Given a text file with a list of server names, it will try to remotely retrieve it's IP address and ping status (both from reading the output of a ping test, so the IP address is sourced from DNS not WMI), the OS (from AD), and if a named service is running (via WMI if the ping test is successful). It outputs the results into a CSV.

You'll just need to change lines 11-15 to suit your needs as per my comments.

Obviously this is pretty basic, but might do while you look at getting something more comprehensive!

Let us know how you get on. (I'd test it on a handful of machines before running in anger)

(P.S - run via cscript from the command prompt as it has echo outputs)
Set objFso = CreateObject("Scripting.FileSystemObject")
Set objTrans = CreateObject("NameTranslate")
Set objShell = CreateObject("Wscript.Shell")
 
Const ForReading = 1
Const ForWriting = 2
Const ADS_NAME_INITTYPE_GC = 3
Const ADS_NAME_TYPE_NT4 = 3
Const ADS_NAME_TYPE_1779 = 1
 
Const strNTDomain = "DOMAIN" ' DOMAIN NETBIOS NAME
Const strDNSSuffix = ".domain.local" 'DOMAIN DNS SUFFIX (INCLUDE THE DOT AT THE START)
Const strFileInput = "D:\servers.txt" 'TEXT FILE WITH LIST OF PCS
Const strCSVFile = "D:\report.csv" 'OUTPUT CSV FILE
Const strGetService = "OpsMgr Health Service" 'NAME OF SERVICE TO CHECK ON
 
Set objTxtIn = objFso.OpenTextFile(strFileInput,ForReading)
 
If Not objFso.FileExists(strCSVFile) Then objFso.CreateTextFile(strCSVFile)
Set objTxtOut = objFso.OpenTextFile(strCSVFile, ForWriting)
 
'INITIALISE THE REPORT
strOutPut = "Name,IP,OS,Ping,Status: " & strGetService & vbcrlf
 
While Not objTxtIn.AtEndOfStream
	strServer = objTxtIn.ReadLine
	WScript.Echo "Processing : " & strServer
	
	'CHECK PING STATUS
	Set objExec = objShell.Exec("ping " & strServer & strDNSSuffix & " -n 2")
	Do
		WScript.Sleep 100
	Loop Until objExec.Status
	strPingOut = objExec.StdOut.ReadAll
	strIP = "": strIP = Mid(strPingOut,InStr(strPingOut,"[")+1,(InStr(strPingOut,"]")) - (InStr(strPingOut,"[")+1))
	If strIP = "" Then 
		strIP = "DNS Lookup Failed"
		WScript.Echo "  ---DNS Lookup Failed"
	End If
	If InStr(strPingOut,"Approximate") > 0 Then 
		strPing = "OK" 
	Else 
		strPing = "FAILED"
		WScript.Echo "  ---Ping Failed"
	End If
		
	'GET YOUR AD ATTRIBUTES HERE....
	On Error Resume Next
	Set objComp = getPcObjFromCN(strServer)
	If Err.Number = 0 Then 
		strOS = objComp.operatingSystem 
	Else
		WScript.Echo "  ---LDAP Error binding to server object: " & strServer & " - " & Err.Number & " " & Err.Description
		strOS = "N/A"
	End If	
 
	'GET YOUR WMI ATTRIBUTES HERE....
	If strPing = "OK" Then
		Set objWMI = GetObject("winmgmts:\\" & strServer & strDNSSuffix  & "\root\cimv2")
		'Get Running Services
		Set colItems = objWMI.ExecQuery("Select * from Win32_Service Where Started=True And DisplayName='" & strGetService & "'")
		If colItems.count = 1 Then strServiceRunning = "Running" Else strServiceRunning = "Stopped"
	Else
		strServiceRunning = "N/A"
	End If
	strOutPut = strOutPut + strServer & "," & strIP & "," & strOS & "," & strPing & "," & strServiceRunning & vbCrLf
Wend
 
objTxtOut.Write strOutPut
objTxtOut.Close
objTxtIn.Close
 
Set objFso = Nothing
Set objTrans = Nothing
Set objShell = Nothing
Set objExec = Nothing
Set objWMI = Nothing
Set colItems = Nothing
 
Function getPcObjFromCN(strPCName)
strNTName = strNTDomain & "\" & strPCName & "$"
objTrans.Init ADS_NAME_INITTYPE_GC, ""
objTrans.Set ADS_NAME_TYPE_NT4, strNTName
Set getPcObjFromCN = GetObject("LDAP://" & Replace(objTrans.Get(ADS_NAME_TYPE_1779),"/","\/"))
End Function

Open in new window

0
 

Author Comment

by:wnbtechnology
ID: 24866471
Thank you!  The scripts works, but I ran it against a computer that is not running the OpsMgr Health Service, though the report.csv showed "Running". I had changed a few lines of the code, but it didnt help; see snippet.

Also, there are some servers that return an "Access denied" when the script is trying to gather the information.  I tried running the cmd line under my domain admin account, but that didnt work.  Would the script need to be hard coded to use a super domain admin when running the queries?
Set colItems = objWMI.ExecQuery("Select * from Win32_Service Where Started=True And DisplayName=OpsMgr Health Service" & strGetService & "OpsMgr Health Service")
		If colItems.count = 1 Then strServiceRunning = "Running" Else strServiceRunning = "Stopped"

Open in new window

0
 
LVL 27

Expert Comment

by:bluntTony
ID: 24867265
HI There,

I've made a few tweaks to try to fix the issues. Could you give me the line numbers of any errors you get?

Thanks.
Set objFso = CreateObject("Scripting.FileSystemObject")
Set objTrans = CreateObject("NameTranslate")
Set objShell = CreateObject("Wscript.Shell")
 
Const ForReading = 1
Const ForWriting = 2
Const ADS_NAME_INITTYPE_GC = 3
Const ADS_NAME_TYPE_NT4 = 3
Const ADS_NAME_TYPE_1779 = 1
 
Const strNTDomain = "DOMAIN" ' DOMAIN NETBIOS NAME
Const strDNSSuffix = ".domain.local" 'DOMAIN DNS SUFFIX (INCLUDE THE DOT AT THE START)
Const strFileInput = "D:\servers.txt" 'TEXT FILE WITH LIST OF PCS
Const strCSVFile = "D:\report.csv" 'OUTPUT CSV FILE
Const strGetService = "OpsMgr Health Service" 'NAME OF SERVICE TO CHECK ON
 
Set objTxtIn = objFso.OpenTextFile(strFileInput,ForReading)
 
If Not objFso.FileExists(strCSVFile) Then objFso.CreateTextFile(strCSVFile)
Set objTxtOut = objFso.OpenTextFile(strCSVFile, ForWriting)
 
'INITIALISE THE REPORT
strOutPut = "Name,IP,OS,Ping,Status: " & strGetService & vbcrlf
 
While Not objTxtIn.AtEndOfStream
	strServer = objTxtIn.ReadLine
	strIP = "": strOS = "": strPing = "": strServiceRunning = ""
	WScript.Echo "Processing : " & strServer
	
	'CHECK PING STATUS
	Set objExec = objShell.Exec("ping " & strServer & strDNSSuffix & " -n 2")
	Do
		WScript.Sleep 100
	Loop Until objExec.Status
	strPingOut = objExec.StdOut.ReadAll
	On Error Resume Next
	strIP = Mid(strPingOut,InStr(strPingOut,"[")+1,(InStr(strPingOut,"]")) - (InStr(strPingOut,"[")+1))
	On Error Goto 0
	If strIP = "" Then 
		strIP = "DNS Lookup Failed"
		WScript.Echo "  ---DNS Lookup Failed"
	End If
	If InStr(strPingOut,"Approximate") > 0 Then 
		strPing = "OK" 
	Else 
		strPing = "FAILED"
		WScript.Echo "  ---Ping Failed"
	End If
		
	'GET YOUR AD ATTRIBUTES HERE....
	On Error Resume Next
	Set objComp = getPcObjFromCN(strServer)
	If Err.Number = 0 Then 
		strOS = objComp.operatingSystem 
	Else
		WScript.Echo "  ---LDAP Error binding to server object: " & strServer & " - " & Err.Number & " " & Err.Description
		strOS = "N/A"
	End If	
	Err.Clear
	'GET YOUR WMI ATTRIBUTES HERE....
	If strPing = "OK" Then
		Set objWMI = GetObject("winmgmts:\\" & strServer & strDNSSuffix  & "\root\cimv2")
		'Get Running Services
		Set colItems = objWMI.ExecQuery("Select * from Win32_Service Where DisplayName='" & strGetService & "'")
		If Err.Number = 0 Then
			If colItems.count = 1 Then 
				For Each objService In colItems
					If objService.Started = True Then strServiceRunning = "Running" Else strServiceRunning = "Stopped" 
				Next
				
			Else 
				strServiceRunning = "Not Found"
			End If
		Else
			strServiceRunning = "N/A"
			WScript.Echo "  ---Error accessing WMI on " & strServer & ". Error " & Err.Number & " - " & Err.Description
		End If
		Err.Clear
	Else
		strServiceRunning = "N/A"
	End If
	strOutPut = strOutPut + strServer & "," & strIP & "," & strOS & "," & strPing & "," & strServiceRunning & vbCrLf
	On Error Goto 0
Wend
 
objTxtOut.Write strOutPut
objTxtOut.Close
objTxtIn.Close
 
Set objFso = Nothing
Set objTrans = Nothing
Set objShell = Nothing
Set objExec = Nothing
Set objWMI = Nothing
Set colItems = Nothing
 
Function getPcObjFromCN(strPCName)
strNTName = strNTDomain & "\" & strPCName & "$"
objTrans.Init ADS_NAME_INITTYPE_GC, ""
objTrans.Set ADS_NAME_TYPE_NT4, strNTName
Set getPcObjFromCN = GetObject("LDAP://" & Replace(objTrans.Get(ADS_NAME_TYPE_1779),"/","\/"))
End Function

Open in new window

0
 

Author Comment

by:wnbtechnology
ID: 24867454
Of course.  Though I ran it against a server that I had permission trouble with last time and the script ran perfect.  Though when I ran it on a machine that doesnt have the OpsMgr Health Service, I received this error.
  ---Error accessing WMI on 0102DTHELP14. Error 424 - Object required

If the service isn't a part of the server that I'm scanning then a N/A would work.

Thanks.
0
 
LVL 27

Accepted Solution

by:
bluntTony earned 500 total points
ID: 24868688
Hi there,

I've made a few more changes. You should get 'Not Found' returned for a server where the service isn't intstalled.

I have tested this here and it works OK, but it can be a bit tricky troubleshooting these sort of problems over these pages. The code below should give a better idea of where the problem is. Fingers crossed!

It may be down to WMI permissions on particular servers...
Set objFso = CreateObject("Scripting.FileSystemObject")
Set objTrans = CreateObject("NameTranslate")
Set objShell = CreateObject("Wscript.Shell")
 
Const ForReading = 1
Const ForWriting = 2
Const ADS_NAME_INITTYPE_GC = 3
Const ADS_NAME_TYPE_NT4 = 3
Const ADS_NAME_TYPE_1779 = 1
 
Const strNTDomain = "DOMAIN" ' DOMAIN NETBIOS NAME
Const strDNSSuffix = ".domain.local" 'DOMAIN DNS SUFFIX (INCLUDE THE DOT AT THE START)
Const strFileInput = "D:\servers.txt" 'TEXT FILE WITH LIST OF PCS
Const strCSVFile = "D:\report.csv" 'OUTPUT CSV FILE
Const strGetService = "OpsMgr Health Service" 'NAME OF SERVICE TO CHECK ON
 
Set objTxtIn = objFso.OpenTextFile(strFileInput,ForReading)
 
If Not objFso.FileExists(strCSVFile) Then objFso.CreateTextFile(strCSVFile)
Set objTxtOut = objFso.OpenTextFile(strCSVFile, ForWriting)
 
'INITIALISE THE REPORT
strOutPut = "Name,IP,OS,Ping,Status: " & strGetService & vbcrlf
 
While Not objTxtIn.AtEndOfStream
	strServer = objTxtIn.ReadLine
	strIP = "": strOS = "": strPing = "": strServiceRunning = ""
	WScript.Echo "Processing : " & strServer
	
	'CHECK PING STATUS
	Set objExec = objShell.Exec("ping " & strServer & strDNSSuffix & " -n 2")
	Do
		WScript.Sleep 100
	Loop Until objExec.Status
	strPingOut = objExec.StdOut.ReadAll
	On Error Resume Next
	strIP = Mid(strPingOut,InStr(strPingOut,"[")+1,(InStr(strPingOut,"]")) - (InStr(strPingOut,"[")+1))
	On Error Goto 0
	If strIP = "" Then 
		strIP = "DNS Lookup Failed"
		WScript.Echo "  ---DNS Lookup Failed"
	End If
	If InStr(strPingOut,"Approximate") > 0 Then 
		strPing = "OK" 
	Else 
		strPing = "FAILED"
		WScript.Echo "  ---Ping Failed"
	End If
		
	'GET YOUR AD ATTRIBUTES HERE....
	On Error Resume Next
	Set objComp = getPcObjFromCN(strServer)
	If Err.Number = 0 Then 
		strOS = objComp.operatingSystem 
	Else
		WScript.Echo "  ---LDAP Error binding to server object: " & strServer & " - " & Err.Number & " " & Err.Description
		strOS = "N/A"
	End If	
	Err.Clear
	'GET YOUR WMI ATTRIBUTES HERE....
	If strPing = "OK" Then
		Set objWMI = GetObject("winmgmts:\\" & strServer & strDNSSuffix  & "\root\cimv2")
		If Err.Number = 0 Then
			Set colItems = objWMI.ExecQuery("Select * from Win32_Service Where DisplayName='" & strGetService & "'")
			If Err.Number = 0 Then
				If colItems.count = 1 Then 
					For Each objService In colItems
						If objService.Started = True Then strServiceRunning = "Running" Else strServiceRunning = "Stopped" 
					Next
					
				Else 
					strServiceRunning = "Not Found"
				End If
			Else
				strServiceRunning = "N/A"
				WScript.Echo "  ---Error querying WMI on " & strServer & ". Error " & Err.Number & " - " & Err.Description
			End If
			Err.Clear
		Else
			WScript.Echo "  ---Error connecting to WMI on " & strServer & strDNSSuffix & ". Error " & Err.Number & " - " & Err.Description	
		End If
	Else
		strServiceRunning = "N/A"
	End If
	strOutPut = strOutPut + strServer & "," & strIP & "," & strOS & "," & strPing & "," & strServiceRunning & vbCrLf
	On Error Goto 0
Wend
 
objTxtOut.Write strOutPut
objTxtOut.Close
objTxtIn.Close
 
Set objFso = Nothing
Set objTrans = Nothing
Set objShell = Nothing
Set objExec = Nothing
Set objWMI = Nothing
Set colItems = Nothing
 
Function getPcObjFromCN(strPCName)
strNTName = strNTDomain & "\" & strPCName & "$"
objTrans.Init ADS_NAME_INITTYPE_GC, ""
objTrans.Set ADS_NAME_TYPE_NT4, strNTName
Set getPcObjFromCN = GetObject("LDAP://" & Replace(objTrans.Get(ADS_NAME_TYPE_1779),"/","\/"))
End Function

Open in new window

0
 

Author Comment

by:wnbtechnology
ID: 24902688
The script works well now.  The issue is just permissions.  I have service accounts that can span across the entire network with the necessary permissions.

Thank you for all your help!  It was valuable.
0
 

Author Closing Comment

by:wnbtechnology
ID: 31601949
The script helped gather the necessary information needed with little overhead.
Thanks.
0
 

Expert Comment

by:MrSampsonite
ID: 33577461
This script looks great. How do I modify it to get the Service Pack level?

Thanks.
0

Featured Post

Windows Server 2016: All you need to know

Learn about Hyper-V features that increase functionality and usability of Microsoft Windows Server 2016. Also, throughout this eBook, you’ll find some basic PowerShell examples that will help you leverage the scripts in your environments!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Had a business requirement to store the mobile number in an environmental variable. This is just a quick article on how this was done.
Group policies can be applied selectively to specific devices with the help of groups. Utilising this, it is possible to phase-in group policies, over a period of time, by randomly adding non-members user or computers at a set interval, to a group f…
Video by: Steve
Using examples as well as descriptions, step through each of the common simple join types, explaining differences in syntax, differences in expected outputs and showing how the queries run along with the actual outputs based upon a simple set of dem…
This tutorial will walk an individual through the process of configuring their Windows Server 2012 domain controller to synchronize its time with a trusted, external resource. Use Google, Bing, or other preferred search engine to locate trusted NTP …

707 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question