Finding inactive machines using Active DirectoryAugust 4, 2004 In a large organization, it can be difficult to find active and inactive machines as well as machines that are not used anymore. This article provides a basic guideline to query the Active Directory and ping all the machines on the network, in order to find all active and inactive machines on the network. Step 1Create a folder c:\pingall and create c:\pingall\container.txt (shown below), which will hold all the containers. Please change the information according to your Active Directory containers. Container.txt ou=Servers,ou=XYZ,ou=YourGroup,ou=USCOMP, dc=Americas,dc=win,dc=yourcompany,dc=com ou=Servers,ou=XYZ,ou=YourGroup,ou=USCOMP, dc=Americas,dc=win,dc=yourcompany,dc=com ou=Workstations,ou=ABC,ou=YourGroup,ou=USCOMP, dc=Americas,dc=win,dc=yourcompany,dc=com ou=Servers,ou=DEVELOPMENT,ou=YourGroup,ou=USCOMP, dc=Americas,dc=win,dc=yourcompany,dc=com ou=Servers,ou=JAX,ou=YourGroup,ou=USCOMP, dc=Americas,dc=win,dc=yourcompany,dc=com ou=Servers,ou=NYC,ou=YourGroup,ou=USCOMP, dc=Americas,dc=win,dc=yourcompany,dc=com ou=Servers,ou=ABC,ou=YourGroup,ou=USCOMP, dc=Americas,dc=win,dc=yourcompany,dc=com ou=Servers,ou=UTH,ou=YourGroup,ou=USCOMP, dc=Americas,dc=win,dc=yourcompany,dc=com ou=Servers,ou=HQL,ou=CHI,ou=YourGroup,ou=USCOMP, dc=Americas,dc=win,dc=yourcompany,dc=com ou=Servers,ou=FM,ou=CHI,ou=YourGroup,ou=USCOMP, dc=Americas,dc=win,dc=yourcompany,dc=com ou=Servers,ou=CAL,ou=CHI,ou=YourGroup,ou=USCOMP, dc=Americas,dc=win,dc=yourcompany,dc=com ou=Servers,ou=MRS,ou=CHI,ou=YourGroup,ou=USCOMP, dc=Americas,dc=win,dc=yourcompany,dc=com ou=Workstations,ou=XYZ,ou=YourGroup,ou=USCOMP, dc=Americas,dc=win,dc=yourcompany,dc=com ou=Workstations,ou=DEVELOPMENT,ou=YourGroup,ou=USCOMP, dc=Americas,dc=win,dc=yourcompany,dc=com ou=Workstations,ou=JAX,ou=YourGroup,ou=USCOMP, dc=Americas,dc=win,dc=yourcompany,dc=com ou=Workstations,ou=NYC,ou=YourGroup,ou=USCOMP, dc=Americas,dc=win,dc=yourcompany,dc=com ou=Workstations,ou=ABC,ou=YourGroup,ou=USCOMP, dc=Americas,dc=win,dc=yourcompany,dc=com ou=Workstations,ou=UTH,ou=YourGroup,ou=USCOMP, dc=Americas,dc=win,dc=yourcompany,dc=com ou=Workstations,ou=HQL,ou=CHI,ou=YourGroup,ou=USCOMP, dc=Americas,dc=win,dc=yourcompany,dc=com ou=Workstations,ou=FM,ou=CHI,ou=YourGroup,ou=USCOMP, dc=Americas,dc=win,dc=yourcompany,dc=com ou=Workstations,ou=CAL,ou=CHI,ou=YourGroup,ou=USCOMP, dc=Americas,dc=win,dc=yourcompany,dc=com ou=Workstations,ou=MRS,ou=CHI,ou=YourGroup,ou=USCOMP, dc=Americas,dc=win,dc=yourcompany,dc=com Step2Create a file, c:\Pingall\PingAll.vbs, then copy and paste the below VBScript into it.
'Objective: Query Active Directory and ping all the machines
'Created by :MAK
'Date: July 15, 2004
OutputFile="C:\PingAll\pingSuccessful.txt"
Set oFSO = CreateObject("Scripting.FileSystemObject")
Set oFile = oFSO.CreateTextFile(OutputFile, True)
OutputFile2="C:\PingAll\pingFailed.txt"
Set oFSO2 = CreateObject("Scripting.FileSystemObject")
Set oFile2 = oFSO.CreateTextFile(OutputFile2, True)
Set iFSO = CreateObject("Scripting.FilesyStemObject")
InputFile="c:\pingall\container.txt"
Set ifile = iFSO.OpenTextFile(inputfile)
Do until ifile.AtEndOfLine
strComputerContainer = ifile.ReadLine
'Remove the Following lines between start and end
'if you dont want timestamp and container names
'start
oFile.WriteLine now()
oFile.WriteLine("Container: " & strComputerContainer)
oFile.WriteLine("---------------------------------------------------")
oFile2.WriteLine now()
oFile2.WriteLine("Container: " & strComputerContainer)
oFile2.WriteLine("---------------------------------------------------")
'end
Set objContainer = GetObject("LDAP://" & strComputerContainer)
objContainer.Filter = Array("Computer")
' Change the value of OutputFile (if you wish)
Set StdOut = WScript.StdOut
Set objShell = CreateObject("WScript.Shell")
On Error Resume Next
For Each objComputer In objContainer
' WScript.Echo strComputer
strComputer = Split(objComputer.Name, "=")(1)
Set objScriptExec = objShell.Exec("ping -n 2 -w 1000 " & strComputer)
strPingResults = LCase(objScriptExec.StdOut.ReadAll)
If InStr(strPingResults, "reply from") Then
' StdOut.WriteLine "ERROR: " & strComputer & " [Ping SuccessFul]"
oFile.WriteLine(strComputer )
Else
' StdOut.WriteLine "ERROR: " & strComputer & " [Ping failed]"
oFile2.WriteLine(strComputer )
End If
Next
Loop
MsgBox "Processing Done "
Step 3:Execute the vbscript using cscript as shown in figure 1.1.
(figure 1.1) cd\ This will create pingSuccessful.txt and pingFailed.txt under the same folder, as shown in figure 1.2
(figure 1.2) The pingSuccessful.txt file holds all of the pingable machine names while pingFailed.txt contains all of the non-pingable machine names. The PingSuccessful.txt will resemble: 07/16/2004 12:38:34 PM ou=Servers,ou=XYZ,ou=YourGroup,ou=USCOMP,dc=Americas,dc=win,dc=yourcompany,dc=com --------------------------------------------------- SUSSERVER MYServerDEVS001 MYServerDEVS002 MYServerDEVS003 MYServerDEVS004 MYServerDEVS005 MYServerDEVS006 MYServerDEVS009 MYServerDEVS010 MYServerDEVS011 MYServerDEVS012 MYServerDEVS013 MYServerDEVS015 MYServerDEVS016 MYServerDEVS018 MYServerDEVS019 MYServerDEVS020 MYServerDEVS021 Step 4:Soon after the VBScript pings all of the machines, it will display a message as shown in figure 1.3
(figure 1.3) Step 5:Create a database, tables and import both of the text files as shown: use Master go create database PingAll go use PingAll go create table PingTable (id int identity(1,1), machinename varchar(200), pingstatus varchar(10), datestamp datetime default getdate()) go create table #pingtable (machinename varchar(200)) go BULK INSERT #pingtable FROM 'c:\pingall\pingSuccessful.txt' WITH (ROWTERMINATOR = '\n') go delete from #pingtable where machinename like 'container:%' or machinename like '-------%' go delete from #pingtable where isdate(machinename) =1 go insert into pingtable (machinename,pingstatus) select machinename,'success' from #pingtable go truncate table #pingtable go BULK INSERT #pingtable FROM 'c:\pingall\pingfailed.txt' WITH (ROWTERMINATOR = '\n') go --select * from #pingtable delete from #pingtable where machinename like 'container:%' or machinename like '-------%' go delete from #pingtable where isdate(machinename) =1 go insert into pingtable (machinename,pingstatus) select machinename,'Failed' from #pingtable go truncate table #pingtable go drop table #pingtable Step 6:Query the table. Select * from pintable Results:
Conclusion:This article examined how to find active and inactive machines over a network using Active Directory as the source. Scheduling the above VBScript to run every day and querying the pingtable as shown below will do the trick. select machinename,Count(*) as Days from pingtable where pingstatus ='Failed' group by machinename having count(*)>30 The result will provide the machine names that are not active for more than 30 days. Either these machines are no longer in the network or they have been shutdown for more than 30 days. Active Directory can now be cleaned up based on the results. Download the scripts. |