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 <# .SYNOPSIS 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. .NOTES Name: Get-DirectReport Author: theSysadminChannel Version: 1.0 DateCreated: 2020-Jan-28 .LINK https://thesysadminchannel.com/get-direct-reports-in-active-directory-using-powershell-recursive - .PARAMETER SamAccountName Specify the samaccountname (username) to see their direct reports. .PARAMETER NoRecurse Using this option will not drill down further than one level. .EXAMPLE Get-DirectReport username .EXAMPLE Get-DirectReport -SamAccountName username -NoRecurse .EXAMPLE "username" | Get-DirectReport #> [CmdletBinding()] param( [Parameter( Mandatory = $false, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true )] [string] $SamAccountName, [switch] $NoRecurse ) BEGIN {} PROCESS { $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 } [PSCustomObject]@{ 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.
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.
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.
Your script breaks if there are no EmployeeID in AD.
Happened here and I just removed this if statement.
Thanks for the advice
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.
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
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.