In the Information System of large and medium-sized enterprises, managing the client PC is often prone to problems. Therefore, many large companies have introduced various distributed management systems, such as Norton AntiVirus, BlackICE firewall, and Microsoft SMS (System Management Server) for anti-virus, these systems will install the corresponding client software on the client, usually in the form of services, but for various reasons, these services will stop running or the client has not installed these client services at all, in this way, the management system may have omissions, which may cause problems, such as becoming a virus source due to inability to defend against viruses, releasing software for the client, and managing the customer's PC. Here, we provide a solution to regularly scan the network by IP address and report the status of a specific service.
This solution uses Microsoft. NET and ADO. net, WMI management, and XML in. NET Framework. Its core is a visual basic (VB.. Net program and its two configuration files. The configuration file is in XML format. This program scans the network by IP address to obtain the service status of each system. If the IP address does not correspond to the system, this IP address is ignored. For a system without services installed or services stopped, we run the nbtstat command in another thread to obtain the machine name, user name, MAC address domain, and other information, so that we can find the machine to solve the problem. Second, in order to save the scan results, we need a small database MS-access or MS-SQL server can be, this article uses SQL2000. Finally, in order to present the scan results so that we can take actions, here we use web pages to display the results in the database.
1. VB. NET Program
This program uses two configuration files in XML format, which are read when the program starts. One file defines the CIDR blocks to be scanned, including excluded CIDR blocks. Another file defines the information for connecting to the database and the definition of data tables. The contents of these two files are as follows:
<Iplist>
<IP lanid = "192.168.100."> <exp L = "1" H = "30"/> </IP>
<IP lanid = "192.168.101."/>
<IP lanid = "192.168.102."/>
<IP lanid = "192.168.103."/>
<IP lanid = "192.168.104."> <exp L = "1" H = "40"/> </IP>
</Iplist>
This file defines that five CIDR blocks will be scanned. Two CIDR blocks must be excluded from some addresses (allocated to printers and other devices). For 192.168.100 segments, we exclude from 1 to 30, for 192.168.104 segments, we exclude 1 to 40.
<Dbinfo>
<Server> dbserver </Server>
<DATABASE> DB </DATABASE>
<UID> REPORT </UID>
<PWD> REPORT </PWD>
<Service table = "SERVICE"> SERVICE </SERVICE>
</DBINFO>
This file defines the information required to connect to the database
TAG Meaning
<SERVER> name of the SCANSERVICE Database SERVER
<DATABASE> scanservice database Name
<UID> the database username used to update the SCANSERVICE Database
<PWD> used to update the password of the database user of the SCANSERVICE Database
<SERVICE> the inner of the TAG defines the name of the Service we want to scan,
Here we assume that you want to scan the SERVICE named SERVICE.
The attribute of this TAG defines the table name in the database, which is used to save the scan results.
First, we define a class to obtain the Service status information of a certain IP address, and trigger another thread when the Service status is abnormal to obtain the detailed information of the system.
Imports System. ServiceProcess
Imports System. Xml
Imports System. Threading
Public Class GetStatus
Private IServiceName As String 'service name
Private IMachineIP As String 'IP address
Private ITable As String 'table name in DATESET
'Constructor
Sub New (ByVal Ip As String, ByVal SvcName As String, ByVal updatetable As String)
IMachineIP = Ip
IServiceName = SvcName
ITable = updatetable
End Sub
'The method running by each thread is used to obtain the service status. If the status is abnormal, another thread is triggered to obtain the IP address information.
Sub GetStausF ()
Dim ServiceP As New ServiceController () 'instantiate a ServiceController class
ServiceP. MachineName = IMachineIP
ServiceP. ServiceName = IServiceName
Dim myRow As DataRow
Dim status As String
Dim Run As Boolean = False
Myrow = Ds. Tables (itable). newrow
Try
If servicep. Status. tostring <> "running" then
Status = servicep. Status. tostring if the status is not running, assign the status to the string variable.
Else
Run = true' if the status is running, do not do anything
End if
Catch er as exception 'Below handle exceptions when obtaining status
Status = left (ER. Message, 35)
If instr (status, "Service Control Manager") = 0 then
Status = "Not installed or open service failed" 'this service is Not installed
ElseIf InStr (er. Message, "Manager")> 0 Then
Status = "Can not detected" 'service status is not available
End If
End Try
ServiceP. Close () 'Close ServiceController instance
'If the status is not RUNNING, record the system and trigger the thread to obtain its details.
If Not Run Then
MyRow ("msg") = status
MyRow ("ip") = IMachineIP
SyncLock GetType (AddRow) 'To ensure multithreading, only one write operation is performed on the DataSet and the AddRow class is locked.
Dim AddRowIns As New AddRow (myRow) 'inserts the IP address and status into the DataSet through the AddRow class we write.
End SyncLock
'Trigger another thread to get machine information
Dim HostInfo2 As New HostInfo (IMachineIP)
Dim HostThr2 As New Thread (New ThreadStart (AddressOf HostInfo2.sysInfo ))
HostThr2.Start ()
SyncLock GetType (HostInfoThreadCounter)
HostInfoThreadCounter. counter + = 1 'number of startup threads plus 1
End SyncLock
End if
Synclock GetType (stoppcounter)
Stopthr. addstop ()
End synclock
End sub
End Class
'The only one method for this class is to reduce the number of stopped threads by 1.
Class stoppcounter
Sub addstop ()
Threadcounterstopped = threadcounterstopped + 1
End sub
End Class
'This class is used to insert existing rows into Dataset
Class AddRow
'The first constructor to construct a behavior input parameter
Sub New (ByVal row As DataRow)
Try
Ds. Tables (0). Rows. Add (row)
Catch ee As Exception
End Try
End Sub
'The second constructor updates the existing row with the machine name, username, and other strings as parameters.
Sub New (ByVal IP As String, ByVal user As String, ByVal hostname As String, ByVal Mac As String, ByVal domain As String, ByVal timeout As Char)
Dim rowtimeout as datarow
Try
For each rowtimeout in DS. Tables (0). Select ("IP = '" & IP &"'")
Rowtimeout. Item ("lastuid") = user
Rowtimeout. Item ("name") = hostname
Rowtimeout. Item ("Mac") = Mac
Rowtimeout. Item ("Domain") = domain
Rowtimeout. Item ("timeout") = timeout' set timeout flag to this item
Exit for 'just run once
Next
Catch er As Exception
End Try
End Sub
End Class
'The Due to space limitations, the class code for obtaining machine information based on IP addresses is omitted here.
Imports System. Threading is used to support multithreading
Imports System. xml' is used to analyze parameter files in Xml format
Imports System. data' is used to save the result to the database.
Module Module1
Public ds As New DataSet ()
Public conn1 As SqlClient. SqlConnection 'database connection
Public ipf As String 'IP list file name
Public dbf As String 'database information file
Public ThreadCounterStopped As Integer
Public StopThr As New StoppCounter ()
Sub Main () 'Program Main Program
Dim machineIP As String
Dim iplistF As New Xml. XmlDocument ()
Dim iplist As Xml. XmlNode
Dim ipitem As Xml. XmlNode
Dim DBinfoF As New Xml. XmlDocument ()
Dim DBinfo As Xml. XmlNode
Dim LanID As String
Dim I As Integer
Dim timestart As Integer
Dim ThreadCounterStarted As Integer
ThreadCounterStarted = 0
ThreadCounterStopped = 0
Dim server As String
Dim database As String
Dim uid As String
Dim pwd As String
Dim table As String
Dim connstr, connstr1 As String
Dim ServiceName As String
Dim Purgestr As String
Try
DBinfoF. Load (dbf) 'reads database information files
Catch nodb As Exception
MsgBox (nodb. Message & "Wrong DB info file name .")
Exit Sub
End Try
Try
IplistF. Load (ipf) 'reads the IP list file
Catch noip as exception
Msgbox (noip. Message & "wrong IP list file name .")
Exit sub
End try
'Analyze database information files
Dbinfo = dbinfof. childnodes (0)
Server = dbinfo. childnodes (0). innertext
Database = dbinfo. childnodes (1). innertext
Uid = dbinfo. childnodes (2). innertext
Pwd = dbinfo. childnodes (3). innertext
Servicename = dbinfo. childnodes (4). innertext
Table = DBinfo. ChildNodes (4). Attributes (0). Value
'Construct the connection string based on the analysis result
Connstr1 = "server =" & server & "; database =" & database & "; uid =" & uid & "; password =" & pwd
Conn1 = New SqlClient. SqlConnection (connstr1) 'instantiate the database connection
Conn1.Open () 'Open the database connection
Dim sa As SqlClient. SqlDataAdapter = New SqlClient. SqlDataAdapter ("select * from" & table, conn1)
Dim combu As New SqlClient. SqlCommandBuilder (sa)
Sa. Fill (ds, table) 'Fill DataSet
Ds. Clear () 'clear old data
Dim IPAddress As String
'Analyze the IP list file
Iplist = iplistF. ChildNodes (0)
Dim Ai As Integer
Dim ip1_count As Integer
Dim ipexcep As Xml. XmlNode
For Each ipitem In iplist. ChildNodes
Dim Excep (2, 83) As Integer
LanID = ipitem. Attributes (0). Value 'to obtain the network ID
For I = 2 To 254 'from 2 To 254, IP addresses are constructed based on each network ID
Ai = 0
'The following judgment is to skip the reserved CIDR Block
If ipitem. HasChildNodes Then
Ip1_count = ipitem. ChildNodes. Count
ReDim Excep (2, ip1_count-1)
For Each ipexcep In ipitem. ChildNodes
Excep (0, Ai) = CInt (ipexcep. Attributes (0). Value)
Excep (1, Ai) = CInt (ipexcep. Attributes (1). Value)
Ai = Ai + 1
Next
End If
For AI = 0 to ipdomaincount-1
If I> = excep (0, AI) And I <= excep (1, AI) then
Console. writeline ("Skip reserved address:" & lanid & I. tostring)
Goto skipip
End if
Next
Machineip = lanid & I. tostring 'IP Address
'The following thread is triggered to get the service status
Dim getst as new getstatus (machineip, servicename, table)
Dim getstthread as new thread (New threadstart (addressof getst. getstausf ))
GetStThread. Start ()
ThreadCounterStarted = ThreadCounterStarted + 1 'number of startup threads plus 1
Console. WriteLine ("Thread" & machineIP & "started. Detection "& ServiceName)
'Every time 100 threads are started, the main thread of the program stops for 15 seconds to avoid memory overflow caused by too many threads.
If (ThreadCounterStarted Mod 100) = 0 Then
Console. WriteLine ("waiting .......")
Thread. CurrentThread. Sleep (15000)
GC. Collect () 'force garbage collection to aviod outOfMemory when run with long IP list
End If
SkipIP:
Next
Next
Console. writeline ("exiting program...") 'All threads have been triggered
Finish:
Thread. currentthread. Sleep (5000) 'The following program waits for the end of all threads
GC. Collect ()
If threadcounterstopped = threadcounterstarted and hostinfothreadcounter. Counter = hostinfothreadcounter. counterstop then 'If the thread is triggered, it is equal to the end thread.
Dim row as data. datarow
For each row in DS. Tables (table). Rows
Row. Item ("policime") = now
Next
Purgestr = "delete" & table
Dim com1 As New SqlClient. SqlCommand (Purgestr, conn1)
Com1.ExecuteNonQuery () 'delete old record
Sa. InsertCommand = combu. GetInsertCommand
Sa. Update (ds, table) 'writes new records to the database
Else
GoTo Finish 'Goto finish and wait another 30 seconds
End If
End Sub
You can use the following command to start the program in the DOS window.
Scanservice-I iplist. XML-D dbinfo. xml
2. scanservice Database
The database saves and saves the program running results for Web display. The following table creation script contains the domain name, user name, machine name, IP address, and service status.
Create Table [DBO]. [SERVICE] (
[IP] [varchar] (50) null,
[Status] [varchar] (50) null,
[User name] [varchar] (50) null,
[Machine name] [varchar] (50) null,
[MAC address] [varchar] (50) null,
[Domain] [varchar] (50) null,
[Timeout] [varchar] (10) null,
[Time security] [datetime] (8) null,
)
Summary:
The above is a complete method and a simple and clear solution. If you require skills and performance, you can also make some improvements, such as the use of the thread pool. There are also some aspects that need to be done by yourself, such as displaying the information in the database on the web.