AD cmdlets and domain statistics

So for all those who still does not believe PowerShell is taking manageability to a new level😉 here’s a quick test: can you get basic statistics from your environment using “legacy” technologies such as VBScrip, WMI, ADSI, etc.? Here’s the list of “stuff” you might want to get: number of users, number of locations your company has (and their list), number of departments (and the list), titles, groups, etc. – the list can go on and on – I think you get the idea. Anyone?

With PowerShell you can do that with literally one line commands! And I’ve got an email from one of AD cmdlets team members – Andrei Polevoi – today with some cool examples of how he was using PowerShell to get the info.

Number of users:
PS C:\> (get-QADUser).count

List all departments:
PS C:\> get-qaduser -department * -sl 50000 | select Department | sort -property Department | Get-Unique -asstring

Get number of departments:
PS C:\> $dpts = get-qaduser -department * -sl 50000 | select Department | sort -property Department | Get-Unique -asstring
PS C:\> $dpts.count

PS C:\> $all_cities = get-qaduser -city * -sl 50000 | select City | sort -property City | Get-Unique -asstring
PS C:\> $all_cities.count

PS C:\> $all_titles = get-qaduser -Title * -sl 5000 | select Title | sort -property Title | Get-Unique -asstring
PS C:\> $all_titles.count

PS C:\> (get-qadgroup).count

I bet your VBScripts were slightly more complex?😉

PowerShell just brings AD manageability to the whole new level!

18 Responses to “AD cmdlets and domain statistics”

  1. 1 Daniele Muscetta April 19, 2007 at 7:02 pm

    get-qaduser, get-aqdgroup …. where are those cmdlets ?

  2. 2 Daniele Muscetta April 19, 2007 at 7:09 pm

    oh, nevermind, I found them – I posted the comment too quickly, my bad🙂

  3. 3 Ambers September 7, 2007 at 12:25 pm

    I’m trying to get a list of all groups and their members by displayname.

    I came up with this, but I want to clean up the output by displayname:

    $groups = get-qadgroup -sl 0
    foreach ($group in $groups) {$group
    ” ”

  4. 4 dmitrysotnikov September 7, 2007 at 12:38 pm


    Could you provide an example of what you are trying to get?

    Here’s how I understood the task:

    Get-QADGroup | ForEach-Object {
    “Group: ” + $_.DisplayName
    Get-QADGroupMember $_ | Format-Table DisplayName

    This gives output like this:

    Group: DL1


    Group: DL2


    Is that what you had in mind?

  5. 5 Ambers September 7, 2007 at 5:42 pm

    That is exactly what I had in mind. I’ll change the DisplayName header to read Members and then I’ll be set. Thanks Dmitry.

  6. 6 dmitrysotnikov September 7, 2007 at 8:04 pm

    Glad that I could help!

  7. 7 Bruce September 20, 2007 at 8:58 pm

    How about counting all the members of a list of groups? I have a large list of groups and I want to know how many users that represents. Just a count, no other information. Some groups may be nested.

  8. 8 dmitrysotnikov September 21, 2007 at 11:19 am


    So you have a certain set of groups and need to get a list (or just the number) of total unique users in them, correct?

    This is the script which does the job for me:

    # This function goes through the members of a given group,
    # adds unique new users to the collection,
    # and calls itself for nested groups

    function GetUserMembers($group) {
    # Go through the members of the group
    $group.Members | ForEach-Object {
    # Get the actual object from the DN
    $subitem = Get-QADObject -Identity $_
    # Check object type
    if ($subitem.Type -eq “group”) {
    # If group – call the function to process its members
    } elseif (($subitem.Type -eq “user”) -and ($h.Contains($_) -eq $false)) {
    # If user and not yet in the collection – add it

    # The actual script starts here
    # Create a hash-table collection.
    # Hash table is used so we can do the uniqueness check

    $h = new-object Collections.HashTable

    # Substitute this Get-QADGroup call with your way to get the groups you need.
    # E.g. “Get-QADGroup” will return all groups in the domain,
    # “Get-QADGroup QDL*” will get all starting with QDL, etc.

    Get-QADGroup QDL.SPB.ProgramManagers | foreach {

    # Output the number of users:
    write-Host (“These groups had ” + $h.Count + ” unique users.”)

    # And the full list of members
    “Here’s the full list of unique members:”

    # Let’s clean up the hash-table now

  9. 9 kirkamunro September 21, 2007 at 4:30 pm

    Be careful with this script though. I just looked it over and unless I’m mistaken I don’t believe it properly supports circular group memberships (where group A contains group B and group B also contains group A). As a result, if you have a circular group membership and run this script you will get into an endless loop that will terminate once the maximum nested level has been reached. If you have circular group membership you’ll also need to store a hashtable that keeps track of the names of groups already processed, including the ones that you started with, and ensure that you don’t process a group more than once.

  10. 10 Mike Adams September 24, 2007 at 5:31 pm

    I’m very new to powershell. I found your post because of Ambers’s post. I don’t know where to get the cmdlet you mentioned. Sorry of this basic question, but can you please direct me a little bit?


  11. 12 Matt May 16, 2008 at 1:07 am

    what would be a good replacement for ADSystemInfo in vbscript in Powershell?

    For example in vbscript….

    ‘Group Memebership Variables
    Set ADSysInfo = CreateObject(“ADSystemInfo”)
    Set CurrentUser = GetObject(“LDAP://” & ADSysInfo.UserName)

    ‘Get User Info & Group Membership
    On Error Resume next
    strGroups = LCase(Join(CurrentUser.MemberOf))
    UsrFullName = currentUser.FullName
    UsrName = ws.expandenvironmentstrings(“%username%”)
    UsrEmail = CurrentUser.mail
    UsrHomeDir = CurrentUser.homeDirectory
    UsrScript = CurrentUser.scriptPath

    Can any of the get-QAD provide this?


  12. 13 dmitrysotnikov May 16, 2008 at 9:53 am


    I am not very familiar with VBScript programming for AD. I assume that your code is trying to get attributes of a particular user. In PowerShell, this can be done with:

    Get-QADUser -Name “User’s Name” | Format-List FullName, homeDirectory

    etc. for the list of attributes you want to see.

    AD PowerShell discussion forum at: – is a pretty good place for such howto questions.


  13. 14 Rajdeep October 30, 2008 at 11:44 am

    I want to know how to get the list of members of a group, and the last change date and time.
    The idea is if somehow I can store this info in a file and then check everyday thru cron to see if there is any change in the members, and as soon as there is a change, I want to update a new file and mail the file to the administrator.
    Can someone help me on this?


  14. 15 Dmitry Sotnikov November 2, 2008 at 8:35 pm


    Sorry for not responding right away. A better way to get answers to AD/PowerShell related questions is posting them to the forums at: – there are a lot of smart people there to answer them.🙂

    If you want to know when a group was changed you can just look up its ModificationDate attribute:

    (Get-QADGroup MyGroup).ModificationDate

    or as a table for all groups:

    Get-QADGroup | Format-Table Name, ModificationDate

    This will obviously give you date of any last change – not necessarily in membership.


  1. 1 Domain Statistics with PowerShell continued « Dmitry’s PowerBlog Trackback on April 7, 2007 at 3:12 pm
  2. 2 Carpe Diem: @ Home : Creating an AD Shell Trackback on April 11, 2007 at 5:52 pm
  3. 3 flaphead - Creating an AD Shell Trackback on October 31, 2012 at 7:09 pm

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

My Recent Tweets


The posts on this blog are provided “as is” with no warranties and confer no rights. The opinions expressed on this site are mine and mine alone, and do not necessarily represent those of my employer - WSO2 or anyone else for that matter. All trademarks acknowledged.

© 2007-2014 Dmitry Sotnikov

April 2007
« Mar   May »

%d bloggers like this: