Friday, March 27, 2009

Creating Active Directory accounts with C#

My preferred method for Active Directory administration with .NET is to use the Directory Services API. First off, add a reference to the System.DirectoryServices dll in your project, then add the following to the top of your class to reference that API.

using System.DirectoryServices;

1. Create the Directory Entry object for the user:

DirectoryEntry deUser = new DirectoryEntry();

2. create the object for the parent container for the user:

objUsersContainer = new DirectoryEntry(@"LDAP://ou=Users,dc=mydomain,dc=com");

NOTE: You must be authenticated at this point with an account that has permissions to create Active Directory users on your domain. If you wish to explicitly pass credentials to this object, you can use the following:

objUsersContainer = new DirectoryEntry(@"LDAP://ou=Users,dc=mydomain,dc=com", "userid", "password", AuthenticationTypes.Secure);

3. Bind the user object to its parent container:

deEntry = objUsersContainer.Children.Add("cn=User Test", "user");

NOTES:
1st Parameter:
"cn=User Test". This cn value must be unique to this container, so use some kind of method for finding a unique cn. This can be done with the Directory Searcher. Google this or wait until I add to another post: ) Or comment to this post...i'll help out.

2nd Parameter: "user". This specifies what type of object your child is.

4. Set the required properties:

deEntry.Properties["samaccountname"].Value = "newuserid"; //This is the user's login id
deEntry.Properties["displayname"].Value = "User, Test"; //This is the text that will display in a global address list

5. Save you're changes!:

deEntry.CommitChanges();

There it is! The account should exist in your domain. However, this is most likely not all that need's to be done. The user still needs a password and be enabled to be able to log in and you may wish to set other properties on this account. My next post will cover these methods.

Tuesday, March 24, 2009

The loading gif problem (.NET)

If you've ever felt the need to use a loading gif , you may have run into a few problems.

Displaying the gif before the rest of page finishes loading isn't as simple a task as you would think. The best way I've found to do this is by dynamically writing javascript as the very first instructions of your Page_Load.

Response.Write("<div id="'mydiv'"> ")
Response.Write("Loading data...<img src="loading.gif" />")
Response.Write("</div>")
Response.Write("<script> var mydiv = document.getElementById('mydiv');</script>")
Response.Write("<script language="javascript">")
Response.Write("function StartShowWait(){mydiv.style.display = 'block';}")
Response.Write("function HideWait(){mydiv.style.display = 'none';}")
Response.Write("StartShowWait();</script>")
Response.Flush()


This basically creates a div tag which stores your loading message and the gif. The StartShowWait() function is called, which displays your loading gif and the Response.Flush() function renders this javascript code to your client before the rest of the page finishes loading. If you don't call Response.Flush(), your javascript code will sit on the server until the page is completely loaded.

In the HTML of your page, make sure you include the following javascript snippet to hide the loading gif once the requested page is completely loaded:

<script lang="javascript">
HideWait();
</script>


So are we done now? Depends on whether you want to do some more processing of data and redirect to another page. If you're using .NET, calling:

Response.Redirect("foo.aspx")

You will get a System.Web.HttpException: Cannot redirect after HTTP headers have been sent.

To overcome this, simple call another snippet of javascript to redirect the page and flush the response again:

Response.Write("<script language="javascript">location.href='foo.aspx';</script>")
Response.Flush()


Hopefully this will alleviate some headaches from trying to execute this simple task.

new direction

I'm going to change the direction of my blog. I'm going to post solutions to various programming problems I've encountered. This blog will mainly serve as a reference for myself and hopefully it will help out a few people who have encountered the same problems.