Setting Managers in Active Directory
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.
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.
./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.