Get Direct Reports in Active Directory Using Powershell (Recursive)

It might come in handy from time to time to drill down on a manager’s direct reports in Active Directory. A good use case is if a director or VP wants to send an email to all of their direct reports, and the direct reports of those direct reports. Another use case would be if you were doing an audit comparing your HR system to what is in Active Directory. What ever the reason might be, you can use this script to get direct reports in active directory using Powershell. Pretty neat!!

If you have any questions regarding the script, feel free to leave me a comment and I’ll do my best to get back to you.

Get Direct Reports in Active Directory Using Powershell

Function Get-DirectReport {
#requires -Module ActiveDirectory

    This script will get a user's direct reports recursively from ActiveDirectory unless specified with the NoRecurse parameter.
    It also uses the user's EmployeeID attribute as a way to exclude service accounts and/or non standard accounts that are in the reporting structure.
    Name: Get-DirectReport
    Author: theSysadminChannel
    Version: 1.0
    DateCreated: 2020-Jan-28
    https://thesysadminchannel.com/get-direct-reports-in-active-directory-using-powershell-recursive -   
.PARAMETER SamAccountName
    Specify the samaccountname (username) to see their direct reports.
    Using this option will not drill down further than one level.
    Get-DirectReport username
    Get-DirectReport -SamAccountName username -NoRecurse
    "username" | Get-DirectReport

            Mandatory = $false,
            ValueFromPipeline = $true,
            ValueFromPipelineByPropertyName = $true

        [string]  $SamAccountName,

        [switch]  $NoRecurse

    BEGIN {}

        $UserAccount = Get-ADUser $SamAccountName -Properties DirectReports, DisplayName
        $UserAccount | select -ExpandProperty DirectReports | ForEach-Object {
            $User = Get-ADUser $_ -Properties DirectReports, DisplayName, Title, EmployeeID
            if ($null -ne $User.EmployeeID) {
                if (-not $NoRecurse) {
                    Get-DirectReport $User.SamAccountName
                    SamAccountName     = $User.SamAccountName
                    UserPrincipalName  = $User.UserPrincipalName
                    DisplayName        = $User.DisplayName
                    Manager            = $UserAccount.DisplayName

    END {}



Like always I like to test out my scripts to ensure the content that I am publishing is legit for people to use so I created a sample org chart. This is what that looks like.
Sample org chart

With the above already created in my lab let’s run Get-DirectReport -SamAccountName cio | Sort-Object samaccountname so we can quickly get an org chart for everyone under our CIO. By default it does run recursively so I’ll also run the -NoRecurse parameter to only get the people that are reporting directly to the CIO.

This is what the output looks like.

Get-DirectReport -samaccountname

I’d love to hear your feedback and I hope you can use this in your environment if you ever need a quick org chart using Powershell. As always be sure to check out our Youbtube Channel https://www.youtube.com/c/theSysadminChannel or if you want more Powershell scripts or content, check out our Powershell Category. There is a lot of useful information on both links.

5/5 - (8 votes)

Paul Contreras

Hi, my name is Paul and I am a Sysadmin who enjoys working on various technologies from Microsoft, VMWare, Cisco and many others. Join me as I document my trials and tribulations of the daily grind of System Administration.


    • Happened here and I just removed this if statement.

      Thanks for the advice

  1. Thank you for this! I wanted to update a group and needed a way to pull the direct reports and their direct reports. This worked flawlessly.

  2. How can this be formatted as a table / with auto-size pls?
    I can add 1 field, but if I add more, it truncates to a list even though there’s clearly enough space in the output window.
    I’ve tried adding “ft | -autosize” after the customobject closes, but it formats every row as a table, which makes things worse.

    • The function is returning an array of objects so you want to manipulate the output /outside/ of the function (either on the pipeline or with results stored in a variable). Like Paul shows in the first command of the second screenshot, you want to pipe the results to Format-Table where you can do the -Autosize…

      Get-DirectReport -SamAccountName cio | Format-Table -Autosize

  3. Thanks for sharing this, Paul! It worked great! I added a few more attributes that I needed, and exported to a .csv for the end user, and it was exactly what they needed. I can definitely see using this one quite a bit in the future.

Leave a Reply

Your email address will not be published.