Powershell Script to List all staff reporting to Manager (direct and indirectly)


I have been trying to create a powershell script that queries a user from active directory and outputs a list of all their direct reporters (manager of). However, I also need it to populate all of their indirect managers.

So if we have the following example:

User: A {MANAGES: B, C, D}
User B: {MANAGES: E, F, G}
User C: {MANAGES: H, I}
User F: {MANAGES: J, K, L}


I was just wondering if anyone would be able to help my create a script to run, so we select a user and it would retrieve a list of their direct reporters (staff who report to them). Then it would search the users found previously to find staff who would report to them, and so on.

Ideally, I would like to store the results on objects, because after I would like it to create a group of those people.


Your query is not clear. Looks like you want to generate the org chart of a given user. How can you query a user from AD and find their reporting chain in AD? Does your AD a security group associated that particular user(manager) which will have all his/her reportees as it’s members? I believe your requirement is very specific to your environment, try providing a real time examples.

Hi GJ,

Sorry if the above is not clear.

In our organisation we currently do not have any groups based on managers reportees. However, this can be extracted with powershell by:

Get-ADUser -Filter (‘manager -eq “XYZ”’)

Where XYZ is a manager.

However, this only shows direct reporters.

I need to find a recursive search on all reporters to the specified manager. For example - please see my attachment.

In the attachment, i want a script which will show the all users under ‘Manager’ as they all report to ‘Manager’ directly and indirectly.

So, it should show:

Manager: A, B, C
A: D, E, F
B: G
C: G, I

By doing this, I can then create a group.


Give this a try. You need access to the Active Directory module.

Function Get-SubordinateData
Param (


    Function New-ManagerData
        $Obj = New-Object -TypeName PSObject -Property @{
            "UserName" = $Null
            "DistinguishedName" = $Null
            "DirectReports" = @()
            "DRNames" = @()
            "Manager" = $Null
        Write-Output $Obj
    Function New-DRName
    Param ($Name)
        $Obj = New-Object -TypeName PSObject -Property @{
            "Name" = $Name
        Write-Output $Obj

    # Create a dynamic array to hold all of the objects to
    # be sent to the pipeline.
    $UserArray = @()

    # Do the initial population of the ManagerSubordinateData
    # Objects
    ForEach ($U in $UserList)
        $Obj = New-ManagerData
        $Obj.UserName = $U.Name
        $Obj.DistinguishedName = $U.DistinguishedName
        $Obj.Manager = $U.Manager
        $UserArray += $Obj
    # Cycle through all of the user objects passed to this function
    # and add subordinate data to the managers.
    For ($X = 0; $X -lt $UserList.count; $X++)
        # If a User Object has a manager, process it.
        If ($UserList[$X].Manager)
            # Get the Distinguished Name of the user's manager. 
            $UserManager = $UserArray |
                Where-Object DistinguishedName -eq $UserList[$X].Manager 
            # Assign that manager the Distinguished name and the Name of
            # the subordinate in the ManagerSubordinateData object.
            $UserArray | Where DistinguishedName -eq $UserManager.DistinguishedName |
                ForEach-Object {
                    $_.DirectReports += New-DRName -Name "$($UserList[$X].DistinguishedName)"
                    $_.DRNames += New-DRName -Name "$($UserList[$X].Name)"
    # Write the data to the pipeline.
    Write-output $UserArray