PowerShell How-To
How To Build a PowerShell Active Directory Sync Tool
If employees have unique identifiers, getting a tool up and running to sink with AD is a cinch.
- By Adam Bertram
- 01/12/2017
A common use for PowerShell is creating a tool that takes input from a data source and syncs with Active Directory (AD). This is typically done against a CSV file or even from a database that contains employee information. Regardless of the source, they all include a standard set of attributes like employee first name, last name, department, etc. Rather than opening up an Excel spreadsheet and doing a whole lot of copy/pasting of reach of these attributes, organizations are automating this conventional process with PowerShell.
Let's break down what it takes to create a tool in PowerShell that can accept employee information from a data source and sync that information to AD to either create new user accounts or modify attributes of existing accounts.
Before starting to build, there's a critical component that you must decide on. That is how to uniquely identify an employee in both your data source as well as Active Directory. For example, some companies have employee IDs that exist in an HR database and have an EmployeeID attribute in AD that's unique amongst all employees. If you don't have a unique identifier for each employee, this job is going to be astronomically harder and prone to error. I suggest validating this and ensure each ID is unique with no exceptions before going any further.
Once a unique identifier has been found, it's now time to get coding. The first task will be to pull information from your data source. For this article, I'll just be using a CSV file that has the following fields:
FirstName, LastName, Department, EmployeeID
I'll first assign each of the rows inside of this CSV file to a variable.
$employees = Import-Csv -Path C:\Employees.csv
Once I've done this, I'll now need to figure out a way to find a 1:1 match between the unique identifier in my data source (EmployeeID, in this case) and AD. I'm going to assume an AD attribute of EmployeeID is also assigned to each user account. This will allow me to make a match.
I'll first need to iterate through each of the employees in the CSV file and find a match in AD based off of their employee ID.
@($employees).foreach({
if ($adUser = Get-AdUser -Filter "EmployeeId -eq $_.EmployeeId) {
} else {
Write-Warning -Message "Could not find a match for employee ID [$($_.EmployeeId)]"
}
})
Note: I'm assuming the Active Directory PowerShell module is installed, and the user has permission to read user objects from AD.
In the example, above, I'm attempting to find the corresponding employee AD user account and assigning it to the $adUserMatch variable. If a match is found, it will return $true for the if statement, and we can modify any attributes necessary. If not, we can display a message.
Once I've found the match, I can now set what attributes in my CSV file that I'd like applied to the AD account.
@($employees).foreach({
if ($adUser = Get-AdUser -Filter "EmployeeId -eq $_.EmployeeId) {
$adUser | Set-AdUser -GivenName $_.FirstName -SurName $_.LastName -Department $_.Department
} else {
Write-Warning -Message "Could not find a match for employee ID [$($_.EmployeeId)]"
}
})
This will overwrite any existing AD attribute for the user account for the givenName, surName, and department AD attributes. This will work but can be dangerous! It would be advisable to wrap this code into a function and use the WhatIf parameter before letting this loose in your production environment!
function Invoke-AdSync {
[CmdletBinding(SupportsShouldProcess)]
param(
[string]$CsvFilePath
)
$employees = Import-Csv -Path $CsvFilePath
@($employees).foreach({
if ($adUser = Get-AdUser -Filter "EmployeeId -eq '($_.EmployeeId)'") {
if ($PSCmdlet.ShouldProcess($_.EmployeeId,'Set employee attributes') {
$adUser | Set-AdUser -GivenName $_.FirstName -SurName $_.LastName -Department $_.Department
}
} else {
Write-Warning -Message "Could not find a match for employee ID [$($_.EmployeeId)]"
}
})
}
At this point, you could call the Invoke-AdSync function with the -WhatIf parameter to verify what it would have done rather than letting the script run rampant.
Invoke-AdSync -CsvFilePath 'C:\Employees.csv' -WhatIf
Feel free to steal this code and use it for your own. At this point, you'll have a foundation to use to begin building your own Active Directory sync tool.
About the Author
Adam Bertram is a 20-year veteran of IT. He's an automation engineer, blogger, consultant, freelance writer, Pluralsight course author and content marketing advisor to multiple technology companies. Adam also founded the popular TechSnips e-learning platform. He mainly focuses on DevOps, system management and automation technologies, as well as various cloud platforms mostly in the Microsoft space. He is a Microsoft Cloud and Datacenter Management MVP who absorbs knowledge from the IT field and explains it in an easy-to-understand fashion. Catch up on Adam's articles at adamtheautomator.com, connect on LinkedIn or follow him on Twitter at @adbertram or the TechSnips Twitter account @techsnips_io.