Tuesday, February 2, 2010

OCS 2007 R2 User Provisioning and Deprovisioning with C#

My customers often wish to automate the provisioning and deprovisioning process for OCS.  While I'm not an application developer by training, I was able to develop a simple application in C# that met my customers needs.

Using Visual Studio 2008, I created a new Windows Console application in C#.  To make the code more portable, I decided to experiment with the System.Configuration .NET reference component to pass in configuration variables that are stored in a standard XML configuration file.  This will make the job of changing configuration information much easier on the administrator.

The configuration file must be located in the same directory as the compiled executable and must be named specifically to match the name of the executable and have a .config extension.  A best practice is to create a new file in the Visual Studio IDE Project Explorer window pane.  In my case, the C# namespace will serve as the name of the compiled executable, so my configuration file is named OCSProvision.exe.config

As noted, OCSProvision.exe.config is written using standard XML.  The file looks like this:


Each configuration key is called from within program.cs and variablized as a string that can be used subsequently throughout the application. 


Additional variables are created to handle log file name and a variable that will be used to distinguish if a user that will be deprovisioned has been inactive for a specified amount of time.  Program.cs is the main code page for the application.

The next piece of code will create a log file directory in the location specified by the configuration file.

The log file itself is created using the logpath variable collected from the configuration file and the dt string derived from DateTime.Now. 


The format will output as such:

c:\ocsprovlog\ocslog-01-12-2010 10.01.32AM.log

The next stage in the code is to provision users.  While not the most elegant method, OCS uses WMI as the mechanism for executing administrative tasks.  My fingers are crossed that the OCS product group will follow the Exchange teams lead and provide native PowerShell support for the next release of OCS.

The next bit of code will bind to a specific OU in Active Directory (determined in the configuration file)…


Note: While looking at each item returned by the AD query above, the code will attempt to retrieve the OCS attribute Primary Home Server.  This is a critical step because if this value is populated, the code will do nothing and move on to the next item in the search array.  If this attribute is not present, the code will throw an ArgumentOutOfRangeException error and move to the Exception catch where the OCS enable will occur.  If another type of exception is thrown, the code will move the the standard Exception catch and log the error.  If no exceptions are thrown and the array is fully exhausted, the nowork variable is flipped to TRUE and the code moves to the deprovisioning process.

…search for users that are not OCS-enabled…


…and call the OCS WMI provider. logging a successful enablement.


Several predefined variables will be bound to specific WMI attributes and the user will be OCS-enabled.  A log entry is written for each successful enablement.


A final catch is included to handle any exceptions.


After provisioning is complete, the code will move on to deprovisioning.

OCS deprovisioning will look at a specific OU (designated in the configuration file), validate a user has been there for a specific number of days (also designated in the configuration file), and then remove all OCS-specific attributes, effectively deprovisioning the user.

The first step in the process will query the designated AD OU and pull out the MSRTCSIP-PrimaryUserAddress and the date/time the user object was last modified.


The code will then look at all returned user objects and calculate the number of days have passed since the object was last modified.


If the number of days is greater than the configured value, in our case 7 days, the users OCS attributes are picked up using a WMI query…


…and the user is deprovisioned.


Like the provisioning process, I’m using an specific exception to determine if the there is work to be done and a standard catch to handle any other exceptions.


A log entry is written if no work is done and the log is closed.


My customer CRONs this code to run it on a regular basis.

-Enjoy.  D.

No comments:

Post a Comment