Counting Users by OU with PowerShell

I’ve been following a discussion thread in the PowerShell forum at ScriptingAnswers.com. The post is about counting the number of users in an OU. Well that sounds like fun. We got him started using the Quest AD cmdlets. I thought I’d share some of the code I posted.

The test code he is posting is using Write-Host, which makes puppies cringe everywhere. But this is PowerShell so we need to be thinking about objects. With objects I can sort on a property, export to a CSV, send to a file or whatever. I decided it would be helpful to have an object for each OU that included the OU name, distinguishedname, total number of users, total enabled users and total disabled users. You could also get a count of expired and/or non-expired.

As with most tasks, there is usually several ways to accomplish it. Here’s my approach using the Quest cmdlets.


get-qadobject -type organizationalunit |
foreach {
$u=get-qaduser -SearchRoot $_.dn -SizeLimit 500 -PageSize 2000 -searchscope Onelevel
$total=($u | measure-object).count
$disabled=($u | where {$_.AccountIsDisabled} | Measure-Object).count
$Enabled=$total-$disabled
New-Object psobject -Property @{
Name=$_.Name;
OU=$_.DN;
Description=$_.Description;
TotalUsers=$Total;
Enabled=$Enabled;
Disabled=$Disabled
}
}

The code first gets all organizational units in the domain. You could use the -Searchroot parameter if you wanted to narrow the search. Each OU is then piped to a foreach-object. Here I’m getting all the users specifying the search root. I’ve added some optional parameters for paging but the cmdlet usually is pretty good about these sorts of things. Although one parameter that is important here is SearchScope. Because I’m counting each OU I don’t want to get a count of users in any child OUs. Setting the SearchScope to OneLevel will only return objects in the immediate container. It won’t recursively search.

Once I have the user count, I measure the total number of of users. Then I get a count of all disabled users. Since an account can only be disabled or enabled, the enabled count should be the difference. Finally, I use New-Object to write a custom object to the pipeline with properties for the OU and my user counts.

If you have the Microsoft AD provider and cmdlets, here’s a version you can use:

Get-ADOrganizationalUnit -filter * -property Description |
foreach {
$u=Get-ADUser -filter * -searchbase $_.distinguishedname -ResultPageSize 2000 -resultSetSize 500 -searchscope Onelevel
$total=($u | measure-object).count
$Enabled=($u | where {$_.Enabled} | Measure-Object).count
$Disabled=$total-$Enabled
New-Object psobject -Property @{
Name=$_.Name;
OU=$_.Distinguishedname;
Description=$_.Description;
TotalUsers=$Total;
Enabled=$Enabled;
Disabled=$Disabled
}
}

If you’d like to learn more about managing Active Directory with PowerShell, as luck would have it I’ve written a book on the subject. You can check it out on my Books and Training page.

Updating Multi-Valued Active Directory Properties Part 2

A few weeks ago I posted about updating multi-valued attributes in Active Directory. Part 1 covered how to accomplish this in PowerShell using ADSI. In Part 2 I’ll show you how to accomplish this using the free Active Directory cmdlets from Quest Software. As you’ll see, the over all process isn’t that much different. Except that using cmdlets simplifies a lot of the typing. Continue reading