[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now


Count Computer Objects in Active Directory

Posted on 2009-02-17
Medium Priority
Last Modified: 2013-12-24
I need help creating a script (vb or powershell) to count the total number of computer objects throughout an AD domain. Getting a total count is easy, however I need a script to recursively discover and count enabled computer objects throughout a domain without specifying every path where these objects are located.

Input would be: domain.com

Output would be: distinguishedName where computer objects were discovered, total of enabled computer objects
Question by:ChWCIT
  • 3
  • 3
  • 2
  • +1
LVL 18

Accepted Solution

BSonPosh earned 750 total points
ID: 23665889
If you find yourself doing alot of AD stuff I would get the free quest cmdlets www.quest.com/powershell

Then this can be simply done like this

(get-qadcomputer -sl 0 -enabled).count
LVL 12

Expert Comment

ID: 23666061
Hi There

Have you ever used Saved Queries in Active Directory Users and Computers Snap-In?
Its very easy to use, i've provided steps on how to do what you want

Right Click on Saved Queries in teh ADUC
Click New -> Query
Give it a name like All Computers
Click Define Queries
From Drop Down - Computers
ComputerName = *
Role can be what you choose
Save this

Right-Click on the New Query and click Refresh

If you right-Click in the results window (blank area) and select View -> Add/Remove Columns
You can select Distinguished names
Then right-Click yor Query and select Export List
Select "Save as Type" as Text CSV to makle it Outlook Friendly

This is now there forever and can be refreshed regularly
Saved Queries is quite powerful and can do most things you will need.

Hope this helps


If you really want a VBScript then i can help there too


Author Comment

ID: 23666179
@BSonPosh - I have this utility, however due to the number of records(21,000) the powershell fail with an error of: "more data available"

@Krys K - Good to know, however I can't show where these objects reside, there are no column selection to show where these computer objects are located.
Prepare for your VMware VCP6-DCV exam.

Josh Coen and Jason Langer have prepared the latest edition of VCP study guide. Both authors have been working in the IT field for more than a decade, and both hold VMware certifications. This 163-page guide covers all 10 of the exam blueprint sections.

LVL 18

Expert Comment

ID: 23666199
That is odd ( I have 380k and it works for me albeit slowly.) you can try this

$n = 0
get-qadcomputer -sl 0 -enabled | %{$n++}

Open in new window


Author Comment

ID: 23666349
@BSonPosh, here's what happens.

[PS] C:\>$n = 0
[PS] C:\>get-qadcomputer -sl 0 -enabled | %{$n++}
Get-QADComputer : A parameter cannot be found that matches parameter name 'enabled'.
At line:1 char:31
+ get-qadcomputer -sl 0 -enabled  <<<< | %{$n++}
[PS] C:\>get-qadcomputer -sl 0 | %{$n++}
Get-QADComputer : More data is available.
At line:1 char:16
+ get-qadcomputer  <<<< -sl 0 | %{$n++}
[PS] C:\>
LVL 12

Expert Comment

ID: 23666546
Hi There

I have written a scrip that will do what you want

See how you get on with it.
Save to notepad as a .VBS file

Results are saved to C:\ComputerReport.csv


Option Explicit
	Call MainScript
WScript.Echo "Changes complete. Check the report on C: Drive"
Sub MainScript
' Version 1.0
' Amended by Krystian Karia
' Dated 18-Feb-2009
' Script that gets all the computer names
' and their DistinguishedNames from AD.
' All results are put to a csv file
	On Error Resume Next
	Dim objFSO, objReport
	Dim strReportFile
	Dim strHeader, strMsg
	Dim strComputer
	Dim iSelectedOption
	Dim arrComputers
	Const ForWriting = 2
' Create needed objects
	Set objFSO = CreateObject("Scripting.FileSystemObject")
' Initialize variables
	strHeader = "ComputerName,DistinguishedName"
	strReportFile = "c:\ComputerReport.csv"
' Open the report 
	Set objReport = objFSO.OpenTextFile(strReportFile, ForWriting, True)
' Enter the header
	objReport.WriteLine strHeader
' Ask where to get our machine list from
		strMsg = strMsg & "Select an option by entering a number only!" & vbNewLine & vbNewLine
		strMsg = strMsg & "1 - Servers Only (From AD)" & vbNewLine
		strMsg = strMsg & "2 - Desktops Only (From AD)" & vbNewLine
		strMsg = strMsg & "3 - All Machines (From AD)" & vbNewLine & vbNewLine
	iSelectedOption = InputBox(strMsg, "Select an Option", "1")
		Select Case Trim(iSelectedOption)
			Case "1"
				arrComputers = GetObjectArrayFromAD("Servers", "")
			Case "2"
				arrComputers = GetObjectArrayFromAD("Desktops", "")
			Case "3"
				arrComputers = GetObjectArrayFromAD("AllMachines", "")
			Case Else
				WScript.Echo "An invalid option was made or you cancelled"
		End Select
' Loop each computer
	For Each strComputer In arrComputers
		If strComputer = "" Then
			Exit For
		End If 
		objReport.WriteLine strComputer
End Sub
Private Function GetObjectArrayFromAD(sArgComputerType, sArgDCName)
' Version 1.0
' ~¬~¬~¬~¬~¬~¬~¬~¬~¬~¬~¬~¬~¬~¬~¬~¬~¬~¬~¬~¬~¬~¬~¬~¬~¬~¬~¬~¬~¬~¬~¬~¬~¬~¬~¬~¬~¬~¬~
'	Function Written by Krystian Karia
'	Description:	Function that searches AD based on the criteria
'					that you pass to it and returns an Array
'	Use:			Pass the Machine Type and optional Domain Controller ServerName
'	Example:		arrMyComputerArray = GetObjectArrayFromAD("servers" | "desktops" | "allmachines" ["dcservername"])
'	Returns:		An array of all required computer objects found
'	Version:		Version 1.0		Created on 06-08-2007
' ~¬~¬~¬~¬~¬~¬~¬~¬~¬~¬~¬~¬~¬~¬~¬~¬~¬~¬~¬~¬~¬~¬~¬~¬~¬~¬~¬~¬~¬~¬~¬~¬~¬~¬~¬~¬~¬~¬~
	On Error Resume Next
	Dim oRoot
	Dim strBase, strFilter, strCriteria, strLevel
	Dim adoConnection, adoCommand, adoRecordset
	Dim strQuery, strContents
	Dim arrResults
	Dim i
' Get the Domain you are currently in
	Set oRoot = GetObject("LDAP://rootDSE")
		strBase = oRoot.Get("defaultNamingContext")
			If Err.Number<> 0 Then
				WScript.Echo "Unable to get the current domain name - Is the machine this script ran on a part of one?" _ 
					& VbCrLf & "Error: " & Err.Number _ 
					& VbCrLf & Err.Source _
					& VbCrLf & Err.Description
				GetObjectArrayFromAD = False
			End If 
' Build the Filter string according to our computer type request
	Select Case UCase(sArgComputerType)
		Case "SERVERS" 
			strFilter = "(&(&(&(sAMAccountType=805306369)(objectCategory=computer)(operatingSystem=*Server*))))"
			strFilter = "(&(&(sAMAccountType=805306369)(objectCategory=computer)(!operatingSystem=*Server*)))"
			strFilter = "(&(&(&(sAMAccountType=805306369)(objectCategory=computer)(samAccountName=*))))"
		Case Else
			Exit Function
	End Select
' Set our Attribute Criteria and Search Level
	 	strCriteria = "sAMAccountName,distinguishedName"
 		strLevel = "SubTree"
' Build our complete query string using the DC Server Name if passed
	If sArgDCName <> "" Then
		strQuery = "<LDAP://" & sArgDCName & "/" & strBase & ">;" & strFilter & ";" & strCriteria & ";" & strLevel
		strQuery = "<LDAP://" & strBase & ">;" & strFilter & ";" & strCriteria & ";" & strLevel
	End If
' Set up the connection to Active Directory using ADO
	Set adoConnection = CreateObject("ADODB.Connection")
	Set adoCommand = CreateObject("ADODB.Command")
		adoConnection.Provider = "ADsDSOObject"
		adoConnection.Open = "Active Directory Provider"
		adoConnection.Cursorlocation = 3
	Set adoCommand.ActiveConnection = adoConnection
			If Err.Number <> 0 Then
				WScript.Echo "Unable to open a connection to Active Directory" _
					& VbCrLf & "Error: " & Err.Number _ 
					& VbCrLf & Err.Source _
					& VbCrLf & Err.Description
				GetObjectArrayFromAD = False
			End If 
		adoCommand.CommandText = strQuery
		adoCommand.Properties("Page Size") = 1000
		adoCommand.Properties("Timeout") = 30
		adoCommand.Properties("Cache Results") = False
' Get the recordset results of the query to Active Directory
	Set adoRecordset = adoCommand.Execute
		adoRecordset.Sort = "distinguishedName"
			If Err.Number <> 0 Then
				WScript.Echo "An error occured executing the recordset" _
					& VbCrLf & "Error: " & Err.Number _ 
					& VbCrLf & Err.Source _
					& VbCrLf & Err.Description
				GetObjectArrayFromAD = False
			End If 
' Loop all the records that were found
		Do Until adoRecordset.EOF = True
'			For i = 0 To adoRecordset.Fields.Count - 1
				If NOT IsNull(adoRecordset.Fields("sAMAccountName").Value) Then ' Remove $ symbol from end of machines
					strContents = strContents & Left(adoRecordset.Fields("sAMAccountName").Value, Len(adoRecordset.Fields("sAMAccountName").Value) - 1) & ","
				End If
				strContents = strContents & Chr(34) & adoRecordset.Fields("distinguishedName").Value & Chr(34) & vbNewLine
'			Next
' Close the Recordset and clear the variables
	Set adoRecordset = Nothing
	Set adoCommand = Nothing
	Set adoConnection = Nothing
' Check the contents of the list is not empty
		If Trim(strContents) <> "" Then
			arrResults = Split(strContents, vbNewLine)	' Create an array of the list
				strContents = ""						' Clear the variable as not needed anymore
			GetObjectArrayFromAD = arrResults
			GetObjectArrayFromAD = False
		End If
End Function 'GetObjectArrayFromAD

Open in new window

LVL 71

Assisted Solution

by:Chris Dent
Chris Dent earned 750 total points
ID: 23668320

> Get-QADComputer : A parameter cannot be found that matches parameter name 'enabled'

I don't have that parameter either, but this will return a count of enabled computers:

(Get-QADComputer -SL 0 -LdapFilter "(!userAccountControl:1.2.840.113556.1.4.804:=2)").Count

LVL 71

Expert Comment

by:Chris Dent
ID: 23668364

> I have 380k and it works for me albeit slowly

Mmm how do you get a job there? ;)

LVL 18

Expert Comment

ID: 23669766
doh! Correct you are. It is Get-QADUser that has -enabled. userAccountControl was my next bet.

As for a job... it is a fun place to work with unique challenges, but it requires a special kind of person :) Are you special Chris :P
LVL 71

Expert Comment

by:Chris Dent
ID: 23671075

lol most definitely, but perhaps that's not a good thing :)


Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

Backups and Disaster RecoveryIn this post, we’ll look at strategies for backups and disaster recovery.
Creating a Cordova application which allow user to save to/load from his Dropbox account the application database.
This tutorial will walk an individual through the process of transferring the five major, necessary Active Directory Roles, commonly referred to as the FSMO roles to another domain controller. Log onto the new domain controller with a user account t…
Microsoft Active Directory, the widely used IT infrastructure, is known for its high risk of credential theft. The best way to test your Active Directory’s vulnerabilities to pass-the-ticket, pass-the-hash, privilege escalation, and malware attacks …

834 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