How to Create an Active Directory User Provisioning System

Reading Time: 8 minutes

This blog will detail how I created an Active Directory (AD) user provisioning tool with PowerShell.  It probably won’t be what you expect; the amount of front end entry is almost non-existent. The key to consistency within your enterprise is to take as much of the human element out of the picture as possible.  Without proper edit and control, organizations will find two user objects created by the same employee won’t hold to a standard of entry.  There in lies the key to this project. 

Although the code and the process in this endeavor is new, the original project itself is a rewrite.  Previous team members Steve Laskowski, Richard Narum and Dale Peterson have all written Perl or VB.Net in different forms to create an user object.  This newest process was created in Powershell.  The GUI was developed using Primal Forms by Sapien.  There is both a freeware tool as well as a full version, I opted for the full version.  Primal Forms generated all the lines of code for me, I am by no means a .Net developer but this development tool allowed me to create a tool rather quickly.

The jr admin running this front end script does not have to have any special permissions within AD.  The user just needs the ability to run the script and be able to save an XML file created by the script to a pre-defined location (Queue).  Once this file has been saved, a backend scheduled task (I execute it every minute from 6:00 am to 6:00 pm) to inspect the folder for a new file specially named as defined below.  The file has a random number built into the system to ensure that duplicate names can be created (Even though you can’t create duplicates) and multiple users can create files at the same time, so as you will see the real power is being able to have a secondary process drop XML files into the queue and the process can process them as required.  This will allow an administrator to run a script and drop all the users they need into a folder and generate as many users as needed.  That was the emphasis behind this project, our Human Resources (HR) synchronization process currently when a user is discovered missing within AD a report is generated, with this new process the user can be created without any intervention on the AD side.  One this is complete, we can then examine synchronizing other LDAP systems such as secondary Oracle db’s.

I have provided the Primal Forms so you can modify the form and the attirbutes passed within the xml.  So whatever you want to pass, you can but we went to the absolute minimums so as to keep things consistents as possible.

All of the scripts, xml files and cmd file all reside in the same location.

When the GUI is started, there is a cmd file which verifies that PowerShell has been loaded.  The code is displayed below.

As you can see the check is to see if the Powershell executable exists, if not a message is displayed, if so then call frontEndForm.ps1

 

########################################################################
@echo off
Rem Verify that Powershell is loaded on this desktop before proceeding
if not exist "%systemroot%\system32\Window~1\v1.0\powershell.exe" goto noPowershell
Rem Start up the GUI
net use v: \\server\share\newADUser
v:
cd \
powershell -ExecutionPolicy Unrestricted -command .\frontEndForm.ps1
c:
net use v: /del /y 
Goto End
Rem Can't Proceed, Powershell needs to exist to run the front end script
:NoPowershell
Echo.
Echo.
Echo Powershell not loaded on this workStation
Echo Script aborted
Echo.
Echo.
Pause
:End
########################################################################

 

Once the newUser script is called the form has to be built.  There are several drop down boxes that need to be populated, two by XML files and a third by the user objects within AD.

 

Front End:

There are only four fields for user data entry; User Id, First Name, Middle Initial and Last Name.  Along with this there are eight additional selections; three drop downs and five check boxes.  The drop down boxes Business Unit and Account Type are built from xml files.

 

Business Unit:

The drop down box is populated by the attribute businessUnitNameX and the attribute businessUnitDNX will be used in the backend process to place the new user object in the defined OU.  A partially defined XML file is shown below:

 

<?xml version="1.0"?>

<!– Below is the configuration settings for the newuser Powershell Script

businessUnitX     – Company the new user is defined to work for

businessUnitNameX – Complete Company Name

businessSMTPX     – E-Mail Domain Name

businessUnitDNX   – Distinguished Name of the OU where the new user will be placed

–>

 

<Configuration>

<row>

<businessUnitX>acme</businessUnitX>

<businessUnitNameX>Acme</businessUnitNameX>

<businessSMTPX>acme.com</businessSMTPX>

<businessUnitDNX>OU=Acme,OU=Employees,OU=Users,DC=acme,DC=com</businessUnitDNX>

</row>

<row>

<businessUnitX>apu</businessUnitX>

<businessUnitNameX>Acme Pencil Unit</businessUnitNameX>

<businessSMTPX>acme.com</businessSMTPX>

<businessUnitDNX>OU=APU,OU=Employees,OU=Users,DC=acme,DC=com</businessUnitDNX>

</row>

 

Account Type:

The drop down box is populated by the attribute accountTypeX which will be used in the backend process to prepend the value, along with other values discussed later, on the user account description attribute.  A defined XML file is shown below:

 

<?xml version="1.0"?>

<!– Below is the configuration settings for the newuser Powershell Script

accountTypeX     – Descriptive value used for association the user type being created

–>

 

<Configuration>

<row>

<accountTypeX>Local Administrator</accountTypeX>

</row>

<row>

<accountTypeX>Permanent Employee</accountTypeX>

</row>

<row>

<accountTypeX>Service Account</accountTypeX>

</row>

<row>

<accountTypeX>Temporary Employee</accountTypeX>

</row>

</Configuration>

 

Account Requested By:

This drop down box is populated by all the user accounts, within AD, that exist from a base defined in the XML configuration file.  This leads me into the XML Configuration file, my goal was to allow this script to be installed by just modifying the four XML files.  The values within the Configuration file are

 

Configuration.xml

<?xml version="1.0"?>

<!– Below is the configuration settings for the newuser Powershell Script

Description           – Description to be placed in user attribute

OrganizationalUnit – Distinguished name where to place newly created user

Description           – Value to be placed in the new user's description attribute

Root                    – Root location of where share is to be created for the new user

ScriptPath            – Executable for the logon script for the new user

HomeDrive          – Drive letter for the home drive for the new user

xmlLocation         – Location of xml files that contain the request for the new user .\ = same location as configuration files (Must end with a \)

expirationLength   – Length of time in days, before the account is expired

sqlServerX           – Optional SQL Server Database, if populated then script expects to write to sqlDataBaseX audit details

sqlDataBaseX      – SQL database

–>

 

<Configuration>

<row>

<descriptionX>User Account Created by Powershell Script</descriptionX>

<rootX>\\usera\useradmin$\user</rootX>

<scriptPathX>logonScript.cmd</scriptPathX>

<homeDriveX>z</homeDriveX>

<xmlLocationX>\\server\share\newADUser\queue\</xmlLocationX>

<userBaseX>OU=Employees,OU=Users,DC=acme,DC=com</userBaseX>

<expirationLengthX>90</expirationLengthX>

<smtpServerX>smtp.acme.com</smtpServerX>

<emailFromX>adAdmin@acme.com</emailFromX>

<emailToX>NewActiveDirectoryUserDL@acme.com</emailToX>

<sqlServerX>sqlServer</sqlServerX>

<sqlDatabaseX>adAuditDB</sqlDatabaseX>

</row>

</Configuration>

 

StorageGroups.xml

<?xml version="1.0"?>

<!– Below are the server/storage group/Database's that are randomly selected to where a new user will be created

By duplicating targets you can weight updates to go more often to those if so needed

Pattern is ExchangeServer\StorageGroup\Database

To list out all db's in you enterprise bring up the Exchange Management shell as an admin and key in the following

get-mailboxDatabase

–>

 

<Databases>

<target>

<xmlSGX>exchangeServer\StorageGroup1\MailBox1</xmlSGX>

</target>

<target>

<xmlSGX>exchangeServer\StorageGroup2\MailBox1</xmlSGX>

</target>

</Databases>

 

After “Ok” is selected, the xml file NewUser_UserName_RandomNumber.xml is built via userTemplate.xml from data entered by the jr admin running the gui script.

 

userTemplate.xml

<?xml version="1.0"?>

<!– Below is the configuration settings for the newuser Powershell Script form that is created

aliasX                 – UserId                                                                                                 (Free form entered)

firstNameX        – First name of newly created user                                                           (Free form entered)

mInitialX            – Middle initial of newly created user                                                        (Free form entered)

lastNameX         – Last name of newly created user                                                           (Free form entered)

createdByX        – Computer and User running this tool that created this file                       (From WMI call)

requestedByX     – Person who requested this new user be created                                     (From Drop Down)

businessUnitX     – Business Unit the new user belongs to                                                    (From Drop Down)

accountTypeX     – Type of account this new user is                                                            (From Drop Down)

emailFlgX            – Should this new user not be given an email mailbox                                (Check box – True or False)

postiniFlgX          – Should this new user not be added to Postini for external email inbound (Check box – True or False)

enableAcctFlg     – Should this new user's account be enabled                                             (Check box – True or False)

expireAcctFlg     – Should this new user's account expire after 90 days                                (Check box – True or False)

folderFlgX          – Should this new user not be given an home folder                                   (Check box – True or False)

 

<employee>

<row>

<aliasX></aliasX>

<firstNameX></firstNameX>

<mInitialX></mInitialX>

<lastNameX></lastNameX>

<createdByX></createdByX>

<requestedByX></requestedByX>

<businessUnitNameX></businessUnitNameX>

<accountTypeX></accountTypeX>

<emailFlgX></emailFlgX>

<postiniFlgX></postiniFlgX>

<enableAcctFlgX></enableAcctFlgX>

<expireAcctFlgX></expireAcctFlgX>

<folderFlgX></folderFlgX>

</row>

</employee>

           

 

Example:

newUser_pbbergs_1175854108.xml

<?xml version="1.0"?>

<!– Below is the configuration settings for the newuser Powershell Script form that is created

aliasX                 – UserId                                                                                                 (Free form entered)

firstNameX        – First name of newly created user                                                           (Free form entered)

mInitialX            – Middle initial of newly created user                                                        (Free form entered)

lastNameX         – Last name of newly created user                                                           (Free form entered)

createdByX        – Computer and User running this tool that created this file                       (From WMI call)

requestedByX     – Person who requested this new user be created                                     (From Drop Down)

businessUnitX     – Business Unit the new user belongs to                                                    (From Drop Down)

accountTypeX     – Type of account this new user is                                                            (From Drop Down)

emailFlgX            – Should this new user not be given an email mailbox                                (Check box – True or False)

postiniFlgX          – Should this new user not be added to Postini for external email inbound (Check box – True or False)

enableAcctFlg     – Should this new user's account be enabled                                             (Check box – True or False)

expireAcctFlg     – Should this new user's account expire after 90 days                                (Check box – True or False)

folderFlgX          – Should this new user not be given an home folder                                   (Check box – True or False)

 

–>

<employee>

<row>

<aliasX>pbbergs</aliasX>

<firstNameX>Paul</firstNameX>

<mInitialX>B</mInitialX>

<lastNameX>Bergson</lastNameX>

<createdByX>Computer:pbbergsDesktop  User:acme\adminpbbergs</createdByX>

<requestedByX>Joe Smith</requestedByX>

<businessUnitNameX>Acme Pencil Unit</businessUnitNameX>

<accountTypeX>Permanent Employee</accountTypeX>

<emailFlgX>False</emailFlgX>

<postiniFlgX>False</postiniFlgX>

<enableAcctFlgX>True</enableAcctFlgX>

<expireAcctFlgX>False</expireAcctFlgX>

<folderFlgX>False</folderFlgX>

</row>

</employee>

 

Now that the form is loaded the user can begin to enter data.  The first field is the User Id, once entered the script will verify that the Id doesn’t currently exist.  Both the First and Last Name field are required and once landing on the field a value is required before you can exit.  Middle Initial is an optional field.

 

The rest of the fields are:

 

Business Unit drop down allows you to select the company or business unit within the company the new user works for.  This field is associated with an OU, which points to the location where the new user will be placed.

Account Type drop down allows you to define the type of account being created.  This value is used to populate part of the description field for human documentation.

Requested By drop down allows you to select who was the manager that requested the account be created, this also is used to help populate the description field for human documentation.

Create Mailbox check box allows you to choose whether or not to create a mailbox with the new user

Add Account to Postini check box is a field that prompts a manual process that notifies whether or not the account is to be allowed to receive external e-mail

Enable Account check box allows you to choose whether or not to enable account

Expire Account After 90 Days check box allows you to choose whether or not to expire account after 90 days

Create Home Folder check box allows you to choose whether or not to create a home folder for the user

 

When the form entry is completed and the OK button is selected, edit checks are rerun against the forms entered values.  The first, middle and last names first character are capitalized and all the drop down boxes have had a value populated in them, the user created xml file is created and dropped into the location defined by the

 

Once the file has been dropped (xmlLocationL) there is the backend process that will use these same xml files to process the dropped file.  The powershell process is setup to run every minute, via a scheduled task.  If no file exists the process quits, else edit checks are run and if passed the user is created.

 

The scheduled task is just a basic, per minute task defined in the photos below:

 

 

 

 

 

 

 

 

Once the task has been created the service account running the task needs to have enough permissions to create the user account, the mailbox (If selected) and the home folder (If selected).

 

The location to store the code can be anywhere but the folder structure will need to be as illustrated below (Note: Disregard the colored green and orange circles they are part of Carbonite, my cloud based backup system).

 

The users that will be running the gui will require read only permissions for the folder newADUser since this is where the code repository resides. The only elevated permissions needed for the folder will be read/write for the queue folder. This is where the gui drops the xml file for processing.

With the storage of the files, as follows:

To download the content (In zipped format), click on the zipped link below. I don't like to present zip'd files but I have too many files to be downloaded individually plus I want to ensure the folder structure is properly configured.  Just remember to limit access to this structure.

https://skydrive.live.com/?cid=3B55FC84ED3C1576#cid=3B55FC84ED3C1576&id=3B55FC84ED3C1576%21655

 

In order to allow the task to run properly you will need to load Powershell v 2.0, this will depend on what o/s you are going to run the scheduled task on. I run it on Windows 2008 R2 which was installed through "Features". To learn how to install this you will need to do a Bing search for your o/s.

 

Next you will need the Active Directory module, again since I am running the script on a 2008 R2 box it is handled via Active Directory Web Services (ADWS). If not using 2008 R2 then you will need to use the Active Directory Management Gateway Service.

Active Directory Administration with Windows Powershell http://technet.microsoft.com/en-us/library/dd378937(WS.10).aspx

 

Finally, you will need to install the Exchange Management tools. When this was written I used Exchange 2007, so the link below references this version:

http://technet.microsoft.com/en-us/library/bb232090(EXCHG.80).aspx