Setting Managers in Active Directory

Posted on Jan 25, 2022

There is a lot of inherent power in Active Directory and, in addition to that, organizations will center around it because it does make a lot of sense with regards to authentication and authorization as well as the wide support and flexibility. Part of what AD can do is just be a directory–nothing fancy it just has some (hopefully) helpful information. One of those built-in fields in the Manager field.

Table Of Contents

Start at the beginning

There clearly is a starting point to be had. It could be some type of CSV or HR system export but that’s not actually terribly important. For this example I’ll actually be using an added attribute in AD that is populated by an HR system. Additionally, I will go through this process for all users in an OU. Your organization may be set up differently but it’s not terribly uncommon to see one OU for users and handle exceptions through group memberships.

$users = Get-ADUser -SearchBase "OU=Users,DC=ad,DC=marktoso,DC=com" -filter {name -like '*'} -Property manageridattr,employeeid,manager

There are a lot of options in Get-ADUser as I’m certain you’ve read. This is very straightforward and gets all users in that OU (you can definitely use a -SearchScope if you need to) and acquires the basic information as well as manageridattr, the custom attribute with the Manager’s employee ID number, employeeid which is the employee ID number, and manager. There are some resources online with the actual attributes but these can be extended through the schema and may be unique to some organizations so keep your eyes open. You also may need to ensure that you’re running the query as a user who has access to these attributes on these computer objects in AD.

Small print

There is no warranty implied with this blog post or any of my blog posts–it’s informational but use it at your own risk (or even peril). I assume no responsibility with any damage it may cause nor with any difficulty you may encounter in running it. I cannot and will not tailor any of this to your working environment–that’s your job.

Check yourself

I, appropriately or not, am a fan of the foreach loop. I clearly have a lot of things that I need to perform operations on and the foreach makes that as uncomplicated as it can be.

foreach ($user in $users) {
# ...
}

That’s all it takes. Good stuff. Let’s fill in this loop a bit. There isn’t a lot of error checking necessary here–if you have rigid constraints on what an employee ID is in your organization you can (and likely should) check manageridattr for the validity of that.

foreach ($user in $users) {
    $managerid = ""
    $managerobj = ""

    $managerid = [string] $user.manageridattr
    if (!$managerid) {
        Write-Warning "$($user.employeeid) has no manager information"
        
        # optional - you can just continue if you'd like
        Set-ADUser $user -Clear manager
        continue
    }
}

Let’s just keep rolling if the manager field is empty. There are other actions we could potentially take there but this is bare bones. It’s an option (that you may not want to take) but you can clear that user’s manager attribute right now and keep on going. Let’s add some more into the body of the loop. Assume that this comes right after checking for the $user.manageridattr. It’s important to cast manageridattr as a string because it can come back as something you don’t want.

$managerobj = Get-ADUser -f {employeeid -like $managerid} 
if (!$managerbj) {
    Write-Warning "manager for $($user.employeeid) does not exist: $($user.manageridattr)"
    # again, optional
    Set-ADUser $user -Clear manager
    continue
}

Set-ADUser is going to be the operation that will do something to the user object and, based on the documentation, you knew that already. Using the -Clear operator will successfully clear an attribute. This is a bit different than setting it to empty string and, in the case of manager, you can’t really do that because it expects a distinguished name.

What’s in a name?

There are different types of names in Active Directory and LDAP. The one that we’re concerned with at the moment is the dn or distinguishedname which is usually in the for of CN=Mark Diaz,OU=Users,DC=ad,DC=marktoso,DC=com. That’s not the obvious way to read it but that’s just how convention has formed that name. The cn or canonincalname is the more left-to-right version of that but precious few (if any) AD operations will take a cn as a parameter (from my experience).

Before you wreck yourself

I realize that we’ve already come to a point where we’re clearing the manager attribute and that makes me think that I should point out something really very important. I’ll even use a callout to make sure you see it.

💡 Test your scripts! That’s it! That’s the most important thing I could say.
As I said in Small Print this is for you to apply. I’ve tried to point out where environments can differ and I hope that it’s helpful but it may cause you more headache than it fixes. Knowing the ins and outs of the environment is crucially important and by adjusting the manager field you may change something that shouldn’t be changed. I can’t imagine of a case like that but I’ve also heard of stranger IT processes and procedures so you’ve been warned twice.

Set it and forget it

Let’s continue that loop.

try { 
    if ($user.Manager -ne $managerobj.DistinguishedName) {
        Set-ADUser $user -Replace @{manager=$managerbj.DistinguishedName}
        Write-Output -ForegroundColor Green "Set $($managerobj.employeeid) as manager of $($user.employeeid)"
    }
} catch {
    Write-Error "cannot set $($managerobj.employeeid) as manager of $($user.employeeid)"
}

The -Replace flag for Set-ADUser is how you change a value like manager. There’s more nuance to the other various types of values and that’s definitely a post for another day. The try and catch are there mainly to ensure you don’t run up against an object that you can’t write to (or that, if you do, it won’t tank the entire script and you’ll know about it). With this you can do some orchestration, also a post for another day, to have this run periodically and keep your AD users’ manager attribute up-to-date.

Here’s the full script all put together.

$users = Get-ADUser -SearchBase "OU=Users,DC=ad,DC=marktoso,DC=com" -filter {name -like '*'} -Property manageridattr,employeeid,manager

foreach ($user in $users) {
    $managerid = ""
    $managerobj = ""

    $managerid = [string] $user.manageridattr
    if (!$managerid) {
        Write-Warning "$($user.employeeid) has no manager information"
        # optional - you can just continue if you'd like
        Set-ADUser $user -Clear manager
        continue
    }

    $managerobj = Get-ADUser -f {employeeid -like $managerid} 
    if (!$managerbj) {
        Write-Warning "manager for $($user.employeeid) does not exist: $($user.manageridattr)"
        # again, optional
        Set-ADUser $user -Clear manager
        continue
    }
    try { 
        if ($user.Manager -ne $managerobj.DistinguishedName) {
            Set-ADUser $user -Replace @{manager=$managerbj.DistinguishedName}
            Write-Output -ForegroundColor Green "Set $($managerobj.employeeid) as manager of $($user.employeeid)"
        }
    } catch {
        Write-Error "cannot set $($managerobj.employeeid) as manager of $($user.employeeid)"
    }
}

Please forgive any typos. I hope to come back around and update those as time allows.

Hi, this post was checked with vale which is a content-aware linter. It was checked using the Microsoft style as well as some rules that I made. A summary of those results is below. More details as to how this was put together check out this post. This post had: 3 errors, 32 warnings and 0 suggestions For details on the linting of this post
 ./content/posts/posh-manager-script.md
 14:119   warning  Consider removing 'terribly'.   Microsoft.Adverbs            
 14:204   error    Use 'that's' instead of 'that   Microsoft.Contractions       
                   is'.                                                         
 14:252   warning  Use first person (such as ' I   Microsoft.FirstPerson        
                   ') sparingly.                                                
 14:365   warning  Consider removing 'terribly'.   Microsoft.Adverbs            
 20:47    warning  Use first person (such as       Microsoft.FirstPerson        
                   'I'm') sparingly.                                            
 20:161   warning  Consider removing 'very'.       Microsoft.Adverbs            
 23:60    warning  Use first person (such as       Microsoft.FirstPerson        
                   'my') sparingly.                                             
 23:138   warning  Use first person (such as ' I   Microsoft.FirstPerson        
                   ') sparingly.                                                
 23:251   warning  Use first person (such as ' I   Microsoft.FirstPerson        
                   ') sparingly.                                                
 23:254   error    Use 'can't' instead of          Microsoft.Contractions       
                   'cannot'.                                                    
 23:265   error    Use 'won't' instead of 'will    Microsoft.Contractions       
                   not'.                                                        
 26:1     warning  Use first person (such as 'I,   Microsoft.FirstPerson        
                   ') sparingly.                                                
 26:93    warning  Use first person (such as ' I   Microsoft.FirstPerson        
                   ') sparingly.                                                
 32:34    warning  Try to avoid using              Microsoft.We                 
                   first-person plural like                                     
                   'Let's'.                                                     
 48:1     warning  Try to avoid using              Microsoft.We                 
                   first-person plural like                                     
                   'Let's'.                                                     
 48:80    warning  Try to avoid using              Microsoft.We                 
                   first-person plural like 'we'.                               
 48:89    warning  Consider removing               Microsoft.Adverbs            
                   'potentially'.                                               
 48:260   warning  Try to avoid using              Microsoft.We                 
                   first-person plural like                                     
                   'Let's'.                                                     
 59:411   warning  Consider removing 'really'.     Microsoft.Adverbs            
 61:20    warning  Don't use end punctuation in    Microsoft.HeadingPunctuation 
                   headings.                                                    
 62:79    warning  Try to avoid using              Microsoft.We                 
                   first-person plural like 'we'.                               
 62:468   warning  Use first person (such as       Microsoft.FirstPerson        
                   'my') sparingly.                                             
 65:1     warning  Use first person (such as 'I    Microsoft.FirstPerson        
                   ') sparingly.                                                
 65:16    warning  Try to avoid using              Microsoft.We                 
                   first-person plural like 'we'.                               
 65:52    warning  Try to avoid using              Microsoft.We                 
                   first-person plural like 'we'.                               
 65:106   warning  Use first person (such as       Microsoft.FirstPerson        
                   'me') sparingly.                                             
 65:119   warning  Use first person (such as ' I   Microsoft.FirstPerson        
                   ') sparingly.                                                
 65:149   warning  Consider removing 'really'.     Microsoft.Adverbs            
 65:156   warning  Consider removing 'very'.       Microsoft.Adverbs            
 66:80    warning  Use first person (such as ' I   Microsoft.FirstPerson        
                   ') sparingly.                                                
 67:3     warning  Use first person (such as ' I   Microsoft.FirstPerson        
                   ') sparingly.                                                
 67:125   warning  Use first person (such as ' I   Microsoft.FirstPerson        
                   ') sparingly.                                                
 70:1     warning  Try to avoid using              Microsoft.We                 
                   first-person plural like                                     
                   'Let's'.                                                     
 116:26   warning  Use first person (such as ' I   Microsoft.FirstPerson        
                   ') sparingly.                                                
 118:210  warning  Use first person (such as ' I   Microsoft.FirstPerson        
                   ') sparingly.                                                

3 errors, 32 warnings and 0 suggestions in 1 file.