To get info out of active directory and into a spreadsheet quickly, the pipeline can be used to create some super useful one-liners. Recently I needed to get the Display Name, Email Address and Job Title of members of a specific group. Here's how I went about it.

First, we need the ActiveDirectory module loaded in PowerShell. To see all of the available AD commands available, run:

PS> Get-Command *-ad*

If that doesn't return any results the module may not be loaded or installed. To find out if the ActiveDirectory module is available, run:

PS> Get-Module -ListAvailable  | Where{$_.Name -eq "ActiveDirectory"}

    Directory: C:\Windows\system32\WindowsPowerShell\v1.0\Modules


ModuleType Version    Name                                ExportedCommands
---------- -------    ----                                ----------------
Manifest   1.0.0.0    ActiveDirectory                     {Add-ADCentralAccessPolicyMember, Add-ADComputerServiceAccount...}

If that does not return any results, you will probably need to install RSAT.

To load the ActiveDirectory module run:

PS> Import-Module ActiveDirectory

Now that we have that loaded, we can start to build our command to query AD for the details of the group members. Start by getting the members of the group in question:

PS> Get-ADGroupMember "Team Cap"

distinguishedName : CN=Captain,OU=Users,OU=Musing,DC=musing,DC=local
name              : Captain
objectClass       : user
objectGUID        : af6bd55a-7eef-4cd6-87e7-ac99b8b75d01
SamAccountName    : Captain
SID               : S-1-5-21-2584363240-1718114649-2297085160-1127

distinguishedName : CN=Daredevil,OU=Users,OU=Musing,DC=musing,DC=local
name              : Daredevil
objectClass       : user
objectGUID        : 22517d35-cce7-4bb2-9368-dba985d1d427
SamAccountName    : Daredevil
SID               : S-1-5-21-2584363240-1718114649-2297085160-1128

This command is returning objects which we can then pipe that into the Get-ADUser Command:

PS> Get-ADGroupMember "Team Cap" | Get-ADUser

DistinguishedName : CN=Captain,OU=Users,OU=Musing,DC=musing,DC=local
Enabled           : False
GivenName         : Steve
Name              : Captain
ObjectClass       : user
ObjectGUID        : af6bd55a-7eef-4cd6-87e7-ac99b8b75d01
SamAccountName    : Captain
SID               : S-1-5-21-2584363240-1718114649-2297085160-1127
Surname           : Rogers
UserPrincipalName :

DistinguishedName : CN=Daredevil,OU=Users,OU=Musing,DC=musing,DC=local
Enabled           : False
GivenName         : Matt
Name              : Daredevil
ObjectClass       : user
ObjectGUID        : 22517d35-cce7-4bb2-9368-dba985d1d427
SamAccountName    : Daredevil
SID               : S-1-5-21-2584363240-1718114649-2297085160-1128
Surname           : Murdock
UserPrincipalName :

Notice the properties returned are different from the results returned when only querying the group? This is because we now have an ADUser Object, rather than the ADPrincipal object returned by Get-ADGroupMember. You can confirm this by running the following:

PS> (Get-ADGroupMember "Team Cap")[0] | Get-Member

   TypeName: Microsoft.ActiveDirectory.Management.ADPrincipal

Name              MemberType            Definition
----              ----------            ----------
Contains          Method                bool Contains(string propertyName)
Equals            Method                bool Equals(System.Object obj)
GetEnumerator     Method                System.Collections.IDictionaryEnumerator GetEnumerator()
GetHashCode       Method                int GetHashCode()
GetType           Method                type GetType()
ToString          Method                string ToString()
Item              ParameterizedProperty Microsoft.ActiveDirectory.Management.ADPropertyValueCollection Item(string p...
distinguishedName Property              System.String distinguishedName {get;set;}
name              Property              System.String name {get;}
objectClass       Property              System.String objectClass {get;set;}
objectGUID        Property              System.Nullable`1[[System.Guid, mscorlib, Version=4.0.0.0, Culture=neutral, ...
SamAccountName    Property              System.String SamAccountName {get;set;}
SID               Property              System.Security.Principal.SecurityIdentifier SID {get;set;}

PS> (Get-ADGroupMember "Team Cap" | Get-ADUser)[0] | Get-Member

   TypeName: Microsoft.ActiveDirectory.Management.ADUser

Name              MemberType            Definition
----              ----------            ----------
Contains          Method                bool Contains(string propertyName)
Equals            Method                bool Equals(System.Object obj)
GetEnumerator     Method                System.Collections.IDictionaryEnumerator GetEnumerator()
GetHashCode       Method                int GetHashCode()
GetType           Method                type GetType()
ToString          Method                string ToString()
Item              ParameterizedProperty Microsoft.ActiveDirectory.Management.ADPropertyValueCollection Item(string p...
DistinguishedName Property              System.String DistinguishedName {get;set;}
Enabled           Property              System.Boolean Enabled {get;set;}
GivenName         Property              System.String GivenName {get;set;}
Name              Property              System.String Name {get;}
ObjectClass       Property              System.String ObjectClass {get;set;}
ObjectGUID        Property              System.Nullable`1[[System.Guid, mscorlib, Version=4.0.0.0, Culture=neutral, ...
SamAccountName    Property              System.String SamAccountName {get;set;}
SID               Property              System.Security.Principal.SecurityIdentifier SID {get;set;}
Surname           Property              System.String Surname {get;set;}
UserPrincipalName Property              System.String UserPrincipalName {get;set;}

From here, it's a simple matter of selecting the properties we want with the Get-ADUser command:

PS> Get-ADGroupMember "Team Cap" | Get-ADUser -Properties DisplayName, Title | Select-Object DisplayName, Title

DisplayName     Title
-----------     -----
Captain America Arse Kicker Extraordinaire
Daredevil       Blind Ninja

And exporting them to a csv file. (For more info on exporting to csv, check this post)

PS> Get-ADGroupMember "Team Cap" | Get-ADUser -Properties DisplayName, Title | Select-Object DislayName, Title | Export-Csv "Heros.csv" -NoTypeInformation
PS> Get-Content ".\Heros.csv"
"DisplayName","Title"
"Captain America","Arse Kicker Extraordinaire"
"Daredevil","Blind Ninja"

Job done!

Not quite. If you have nested groups, this method requires tweaking. To illustrate this, have a look at these two groups:

And consider the previous command on the All Heros group:

PS> Get-ADGroupMember "All Heros" | Get-ADUser -Properties DisplayName, Title | Select-Object DisplayName, Title
Get-ADUser : Cannot find an object with identity: 'CN=Team Cap,OU=Groups,OU=Musing,DC=musing,DC=local' under:
'DC=musing,DC=local'.
At line:1 char:33
+ ... ember "All Heros" | Get-ADUser -Properties DisplayName, Title | Selec ...
+                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (CN=Team Cap,OU=...musing,DC=local:ADUser) [Get-ADUser], ADIdentityNotFo
   undException
    + FullyQualifiedErrorId : ActiveDirectoryCmdlet:Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException,M
   icrosoft.ActiveDirectory.Management.Commands.GetADUser

Get-ADUser : Cannot find an object with identity: 'CN=Team Ironman,OU=Groups,OU=Musing,DC=musing,DC=local' under:
'DC=musing,DC=local'.
At line:1 char:33
+ ... ember "All Heros" | Get-ADUser -Properties DisplayName, Title | Selec ...
+                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (CN=Team Ironman...musing,DC=local:ADUser) [Get-ADUser], ADIdentityNotFo
   undException
    + FullyQualifiedErrorId : ActiveDirectoryCmdlet:Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException,M
   icrosoft.ActiveDirectory.Management.Commands.GetADUser

If fails miserably. This is because the group contains groups, and we are passing the GetADGroupMembers output to Get-ADUser. Get-ADUser fails because the objects it receives are not users.

Let's try it with the -Recursive switch on Get-ADGroupMember.

PS> Get-ADGroupMember "All Heros" -Recursive | Get-ADUser -Properties DisplayName, Title | Select-Object DisplayName, Title

DisplayName     Title
-----------     -----
Captain America Arse Kicker Extraordinaire
Daredevil       Blind Ninja
Ironman         Genius, Billionaire, Playboy, Philanthropist.
Spiderman

Now we are getting the users that are part of the group through nested groups. The recursive switch, as the name suggests, ensures we enumerate all the sub groups within the All Heros group.

Now it's job done!

Thanks for reading.