2 minute read

This post was published in 2014 and may be outdated.

Update 2019/06/29: Added an example to do wildcard search

Site MapI’ve been working in the video games industry for a bit more than 3 months now. A lot is going on, and the pace seems faster than regular corporation environment. I also notice a lot of employees movements between teams and projects.

Last week I had an interesting “Quest”: To find the list of employees under a specific manager. In Active Directory you can retrieve this information under the property DirectReports.

However if this manager manage other managers… how can I do a recursive search… ? Sounds like a mission for PowerShell :)

Screenshot from "PowerShell - Who Reports to Whom? (Active Directory recursive DirectReports)" (1)

In the following post, I will use the above diagram as an example to explain how to retrieve the directreports information and show how to find all the “indirect reports.

Get-ADDirectReports function

Get-ADDirectReports is PowerShell functionusing the ActiveDirectory module to retrieve the directreports property. If the switch parameter -Recurse is used, It will report all the indirectreports users under the -Identityaccount specified.

As an example, (assuming the above diagram) we can run the following commands:

# Find all direct user reporting to Test_director
Get-ADDirectReports -Identity Test_director

# Find all Indirect user reporting to Test_director
Get-ADDirectReports -Identity Test_director -Recurse

Get ADDirectReport

Retrieving the DirectReport Property

Using the MMC Active Directory Users and Computers, this property in under the Organization tab of a user object. For example, here is the information for the Director

directreports property mmc

Director - DirectReports using PowerShell

# Find all direct user reporting to Test_director
Get-ADUser -Identity test_director -Properties directreports | Select-Object -ExpandProperty DirectReports

Director directreports powershell 02

Managers - DirectReports

# Find all direct user reporting to Test_managerA
Get-ADUser -Identity test_managerA -Properties directreports | Select-Object -ExpandProperty DirectReports

ManagerA ManagerB directreports powershell 02

Translating the output

We can notice that all the values returned are DistinguishedName. You’ll need to do some extra work to get more information on those accounts. For example let’s say you only want the SamAccountName and Mail properties:

Get-ADUser -Identity test_director -Properties directreports |
    Select-Object -ExpandProperty directreports |
    Get-ADUser -Properties mail |
    Select-Object SamAccountName, mail

Director directreports powershell SamAccountName mail

Recursive DirectReport

We can now create a small function to loop each time some directreports object are found…

Small version

function Get-ADdirectReports
{
    PARAM ($SamAccountName)
    Get-Aduser -identity $SamAccountName -Properties directreports | %{
        $_.directreports | ForEach-Object -Process {
            # Output the current Object information
            Get-ADUser -identity $Psitem -Properties mail,manager | Select-Object -Property Name, SamAccountName, Mail, @{ L = "Manager"; E = { (Get-Aduser -iden $psitem.manager).samaccountname } }
            # Find the DirectReports of the current item ($PSItem / $_)
            Get-ADdirectReports -SamAccountName $PSItem
        }
    }
}

Full version

As a final step we want a flexible function who can return DirectReports and IndirectReports, plus all the nice stuff from PowerShell (Error Handling, Comment Based Help, etc…)

The full version is available below :-)

Download

Someone asked in comment how to do a wildcard search when specifying the -SamAccountName

For this we need to edit the function to use -ldapfilter instead of -Identity.

Here is an example

function Get-ADdirectReports
{
    PARAM ($SamAccountName)
    Get-Aduser -ldapfil "(samaccountname=$SamAccountName)" -Properties directreports |
		ForEach-Object{
        $_.directreports | ForEach-Object -Process {
            # Output the current Object information
            Get-ADUser -identity $Psitem -Properties mail,manager | Select-Object -Property Name, SamAccountName, Mail, @{ L = "Manager"; E = { (Get-Aduser -iden $psitem.manager).samaccountname } }
            # Find the DirectReports of the current item ($PSItem / $_)
            Get-ADdirectReports -SamAccountName $PSItem
        }
    }
}

Once loaded in your session, you can do something like:

Get-ADdirectReports -SamAccountName francoi*

Hope this helps

Leave a comment