Public/Get-ADDirectReports.ps1

<#
.SYNOPSIS
    Retrieves direct reports for a given manager from Active Directory, optionally excluding those with a job title containing "System".
 
.DESCRIPTION
    This function queries Active Directory to find the direct reports of a specified manager account.
    It includes an optional switch to exclude any direct reports whose job title contains the word "System".
 
.PARAMETER sAMAccountName
    The sAMAccountName of the manager.
 
.PARAMETER ExcludeJobTitle
    If enabled, excludes direct reports whose job title contains the word "System".
 
.PARAMETER ExcludeManager
    If enabled, Includes direct reports whose job title contains the word "System".
 
.PARAMETER OnlyIT
    If enabled, Includes direct reports whose department is "Infrastructure Svcs".
 
.EXAMPLE
    Get-ADDirectReports -sAMAccountName "test"
    Retrieves direct reports for the manager 'test' who are located in Asia.
 
.EXAMPLE
    Get-ADDirectReports -sAMAccountName "test" -ExcludeJobTitle
    Retrieves direct reports for the manager 'test' who are located in Asia and excludes those whose job title contains "System".
 
.NOTES
    Requires Active Directory module and appropriate permissions to read Active Directory objects.
#>


function Get-ADDirectReports {

    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true, ValueFromPipeline = $true)]
        [string]$sAMAccountName,

        [switch]$ExcludeJobTitle,
        [switch]$ExcludeManager,
        [switch]$OnlyIT
    )

    begin {
        # Initialize DirectorySearcher and set common properties
        $objSearcher = New-Object System.DirectoryServices.DirectorySearcher
        $Root = [ADSI]"LDAP://RootDSE"
        $Domain = $Root.Get("rootDomainNamingContext")
        $objSearcher.SearchRoot = New-Object ADSI("GC://$Domain")
        $objSearcher.PageSize = 1000
        $objSearcher.SearchScope = "Subtree"
        $objSearcher.PropertiesToLoad.Add("directReports") | Where-Object { -not ($_ -is [int]) } | Sort-Object
    }

    process {
        # Search for the user to get their direct reports
        $objSearcher.Filter = "(&(objectCategory=User)(sAMAccountName=$sAMAccountName))"
        $adAccount = $objSearcher.FindOne()

        if ($adAccount -ne $null) {
            $directReports = $adAccount.Properties["directReports"]

            if ($directReports.Count -gt 0) {
                # Initialize another DirectorySearcher for direct reports
                $reportSearcher = New-Object System.DirectoryServices.DirectorySearcher
                $reportSearcher.SearchRoot = $objSearcher.SearchRoot
                $reportSearcher.PageSize = 1000
                $reportSearcher.SearchScope = "Subtree"
                $reportSearcher.PropertiesToLoad.AddRange(@("sAMAccountName", "name", "userPrincipalName", "ppdjobname", "department"))

                foreach ($report in $directReports) {
                    # Build the filter based on the switches
                    $reportsFilter = "(&(objectCategory=person)(objectClass=user)(distinguishedName=$report))"

                    if ($ExcludeJobTitle) {
                        $reportsFilter = "(&(objectCategory=person)(objectClass=user)(distinguishedName=$report)(!(ppdjobname=*System*)))"
                    }
                    if ($ExcludeManager) {
                        $reportsFilter = "(&(objectCategory=person)(objectClass=user)(distinguishedName=$report)(ppdjobname=*System*))"
                    }
                    if ($OnlyIT) {
                        $reportsFilter = "(&(objectCategory=person)(objectClass=user)(distinguishedName=$report)(department=*Infrastructure Svcs*))"
                    }

                    $reportSearcher.Filter = $reportsFilter
                    $reportAccount = $reportSearcher.FindOne()

                    if ($reportAccount -ne $null) {
                        $output = [pscustomobject]@{
                            Name              = $reportAccount.Properties["name"][0]
                            sAMAccountName    = $reportAccount.Properties["sAMAccountName"][0]
                            UserPrincipalName = $reportAccount.Properties["userPrincipalName"][0]
                        }

                        Write-Output $output
                    }
                }
            } else {
                Write-Warning "No direct reports found for user with sAMAccountName: $sAMAccountName"
            }
        } else {
            Write-Error "User with sAMAccountName: $sAMAccountName not found."
        }
    }

    end {
        # Cleanup
        $objSearcher.Dispose()
        if ($reportSearcher) {
            $reportSearcher.Dispose()
        }
    }
}