2014/10/05

PowerShell - Who Reports to Whom? (Active Directory recursive DirectReports)

I'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 :-)



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 function using the ActiveDirectory module to retrieve the directreports property. If the switch parameter -Recurse is used, It will report all the indirectreports users under the -Identity account 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




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



Director - DirectReports using PowerShell


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



Managers - DirectReports

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



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




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


Thanks for reading! If you have any questions, leave a comment or send me an email at fxcat@lazywinadmin.com. I invite you to follow me on Twitter @lazywinadm / Google+ / LinkedIn. You can also follow the LazyWinAdmin Blog on Facebook Page and Google+ Page.

12 comments:

  1. hey, just tested it but i have an error on the gui when i use it :
    "Loading Error: Type [Cassia.Impl.TerminalServicesSession] introuvable"
    i'm on windows 8.1 x64
    do you know how to solve this error ?.
    best regards

    ReplyDelete
  2. Hey Chris,

    One other person had this issue so far, to resolve it:
    -Make sure the files are unblocked.
    -Also it seems, replacing the cassia.dll with a fresh downloaded one fix it, it can be downloaded here
    https://code.google.com/p/cassia/downloads/list

    ReplyDelete
  3. did it .. but don't work ...exe and .ps1 give me same error..

    ReplyDelete
  4. Hey Chris,


    Hum... weird What is your ExecutionPolicy ? Are your files unblocked ? What is your version of powershell ?

    ReplyDelete
  5. I update the LazyTS page and added "Frequent Issues"
    http://www.lazywinadmin.com/p/lazyts.html



    I hope this help

    ReplyDelete
  6. my policy : Unrestricted , yep i have unblocked all files, my version is 4.0. still have the problem..

    ReplyDelete
  7. no 8-( my policy : Unrestricted , yep i have unblocked all files, my version is 4.0. still have the problem..

    ReplyDelete
  8. Hum... well this is a mystery... Sorry Chris, at this point I don't see where It could come from.
    I could change the PowerShell code to return more error information to help us troubleshoot...

    Other ideas: Maybe check your AV, is the script in a long path..., Run As Admin (elevated mode)

    ReplyDelete
  9. Requires PowerShell version 3 for ordered pscustomobjects. Make sure you use your "#requires -version 3" you lazy admin! :)

    ReplyDelete
  10. I had created something similar back in April/May. I got mine to work with PowerShell version 2 and no GPO modules, which makes it a little less restrictive and much more flexible. I also added a few other things like file and folder count and size, which helps find missing/inconsistent data. You're more than welcome to reference it or add those bits to yours if you think they add value. You can find it here: http://www.jhouseconsulting.com/2014/05/23/script-to-generate-a-group-policy-object-gpo-version-report-1317


    Cheers,
    Jeremy

    ReplyDelete
  11. Very good, and work fine.
    How can add color/style on a row with conditionnal test ?

    ReplyDelete