Counting ConfigMgr Clients with PowerShell

I recently had to write a script that connected to 19 different domains and count how many computer objects exist on the domain so that I can get an idea of how many clients will need to be calculated for a ConfigMgr install.  This was all done at planning stage.  I decided to let PowerShell do the work for me.

From a single point on the network, and thanks to a great setup, I was able to connect to each and every domain controller, in each and every subnet then query the domain controller and get a total count of computers.  Each domain has a different username and/or password so I created myself a simple CSV file which contained the domain controllers name, the username I was going to use to connect to it and of course the password.

The CSV was formatted with three column headers DC, Username and Password. An example row would be DC01, domain\administrator, P@ssw0rd.

First, we import the CSV into a variable like so..

   1: $CSV = Import-CSV .\Details.csv

Next I decided to use two counters, one as a counter for the ForEach loop and one for the Grand Total Count of computers.  I declare them and set them both to Zero.

   1: #Set Everything to Zero
   2: $Count = 0
   3: $GrandTotal = 0

Ok so now we start… using a ForEach command I will first set up the connection details

   1: # Set Username & password
   2: $Username = $CSV.Username[$Count]
   3: $Password = ConvertTo-SecureString $CSV.Password[$Count] -AsPlainText -Force
   4: $Credential = New-Object -typename System.Management.Automation.PSCredential $Username, $Password

Rememeber $Count is currently set to zero. 

And now we’re ready to use Invoke-Command to ask the domain controller for the information we want.  We need to collect the domain dns root name (optional) and the computer count.

   1: $ClientCount = Invoke-Command -ComputerName $CSV.DC[$Count] -Credential $Credential -ScriptBlock {Import-Module activedirectory ; (Get-ADComputer -Filter * | Measure-Object).count} # Close Invoke-Command

This will set the vairable $ClientCount to the amount of computers currently on the domain.  After connecting successfully, it queries AD by first importing the AD module and then using Get-ADComputer to get every computer on the domain.  The result is piped to Measure-Object and we retrieve the count, which is what we need.

Next we get the domain dns root name, this is optional but I used it so I could display what was going on.

   1: $DomainName = Invoke-Command -ComputerName $CSV.DC[$Count] -Credential $Credential -ScriptBlock {Import-Module activedirectory ; (Get-ADDomain).Dnsroot} # Close Invoke-Command

Still inside the ForEach loop I Write-Host to tell me what’s going on

   1: Write-Host "$DomainName contains $ClientCount computers" 

Followed up by adding the client count to the total count of computers

   1: # Set Grand Total
   2: $GrandTotal = $GrandTotal + $ClientCount

Then I increment the counter and the loop starts again for the next domain in the CSV

   1: #Increment Counter
   2: $Count ++

After the ForEach loop has completed I display the total number of clients counted

   1: Write-Host -ForegroundColor Green "GRAND TOTAL SCCM CLIENTS  = $GrandTotal"


For those interested here is the finished code:

   1: <#
   2: Script to count ConfigMgr clients on domains 
   4: Author:  Jonathan of
   5: Version: 1.0.0
   7: #>
  10: #Import CSV
  11: $CSV = Import-Csv .\MercuryCloudDCs.csv
  13: #Set Everything to Zero
  14: $Count = 0
  15: $GrandTotal = 0
  17: ForEach ($Entry in $CSV){
  19:     # Set Username & password
  20:     $Username = $CSV.Username[$Count]
  21:     $Password = ConvertTo-SecureString $CSV.Password[$Count] -AsPlainText -Force
  22:     $Credential = New-Object -typename System.Management.Automation.PSCredential $Username, $Password
  24:     #Invoke commands on remote DC
  25:     $ClientCount = Invoke-Command -ComputerName $CSV.DC[$Count] -Credential $Credential -ScriptBlock {Import-Module activedirectory ; (Get-ADComputer -Filter * | Measure-Object).count} # Close Invoke-Command
  26:     $DomainName = Invoke-Command -ComputerName $CSV.DC[$Count] -Credential $Credential -ScriptBlock {Import-Module activedirectory ; (Get-ADDomain).Dnsroot} # Close Invoke-Command
  27:     Write-Host "$DomainName contains $ClientCount computers" 
  29:     # Set Grand Total
  30:     $GrandTotal = $GrandTotal + $ClientCount
  32:     #Increment Counter
  33:     $Count ++
  35:         } # Close ForEach
  37: Write-Host -ForegroundColor Green "GRAND TOTAL SCCM CLIENTS  = $GrandTotal"

I will revisit this blog when I have time and turn this into a tool addressable from the prompt as good PowerShell people should.

I hope this is useful to someone.