Finding inactive machines using Active Directory

August 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 1

Create 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

Step2

Create 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\
cd\Pingall
Cscript pingall.vbs

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:

2169

Server1

success

7/16/04 14:24

2170

Server2

success

7/16/04 14:24

2171

Workstationx

Failed

7/16/04 14:25

2172

Workstation2

Failed

7/16/04 14:25

2173

Mymachine2

Failed

7/16/04 14:25

2174

MyMachine4

Failed

7/16/04 14:25

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.

» See All Articles by Columnist MAK








The Network for Technology Professionals

Search:

About Internet.com

Legal Notices, Licensing, Permissions, Privacy Policy.
Advertise | Newsletters | E-mail Offers