I am working on a web app to replace a crusty old vendor supplied application for our maintenance work order generation software. The application is primarily a Win32 application and the vendor built this bolt on web app to make it easier to have users generate work requests. The problem I have with it is that it is the most convoluted way to enter a work request with big gaudy buttons and the fact that they charge you on a per logon basis to for the application. It is sold in packs of 25 users and we have used up the initial 25 users and don’t really feel like purchasing more for an application that has not had an update since it’s initial release in 2001!
Anyway I am working on replacing this web app with one of my own creation. One of the good things the original application has is the ability to email the requester any updates that might happen on their request as it makes its way through the maintenance department. The way the vendor app does this is they have another table in the database that you add an email address for each of the 25 users who have access to application. Not a real elegant way to do this, especially when you open up the app for every user in the company as I do not want another database to update if someone comes or goes. The downside of our logon names is that they don’t match up to our email addresses, meaning logon names are a series of characters while email address are first initial plus last name at domain, so I can’t just take the logon name and stick the domain at the end of it. The only way to do this nicely is to talk to AD and do a search on the directory for the mail address using the logon name as the filter.
First thing you need to do is turn off Anonymous Access in IIS to where this app is located. From the IIS manager drill down to the directory where the app is located. Right mouse click on the directory and select PROPERTIES. Click on the Directory Security tab and then in the Authentication and access control, click the Edit button. Remove the tick mark on the Enable anonymous access box and tick Integrated Windows Authentication. Click OK twice to save out the settings. This allows you to capture the intranet user as they access the page.
Then at the top of your page you will need to import the directory services namespace and the assembly and we are also going to import the system.net namespace so we can do a workstation lookup also.
<%@ Import Namespace="System.Net" %>
<%@ Import Namespace="System.DirectoryServices" %>
<%@ Assembly Name="System.DirectoryServices, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"%>
Then in your code you will need to declare your items. You will have to setup the LDAP string to match your own domain.
Dim strUserName, strFullName, strCompName, strEmail, strPhoneExt As String
Dim entry As New DirectoryServices.DirectoryEntry("LDAP://OU=Users,DC=domainname,DC=com")
Dim mySearcher As New System.DirectoryServices.DirectorySearcher(entry)
Then personally I like to plug these items into the page_load but you can do it where ever you want.
Sub page_load(ByVal src As Object, ByVal e As EventArgs)
If Not Page.IsPostBack Then
getUser()
getUserContactInfo()
getWorkstationInfo()
End If
End Sub
Now for each function in the page_load starting first with the getUser. What is happening here is that the logged on username is captured when they access this page. In my domain, usernames are a string of characters that is not the user’s name, so to get the easy to read full name I need to query AD. First I set the strUserName and strip off the domain name so it is just the pre Windows 2000 logon name. In the second portion of this script do the actual query on AD using the stripped down username as a filter to get to the displayName value contained in AD. At the end strFullName will contain a value such as “John Doe”.
Sub getUser()
' set username and trim off the domain name
strUserName = System.Web.HttpContext.Current.User.Identity.Name
strUserName = UCase(strUserName.Replace("DOMAINNAME\", ""))
' search AD for full name
Dim resultFullName As System.DirectoryServices.SearchResult
mySearcher.Filter = ("(sAMAccountName= " & strUserName & ")")
For Each resultFullName In mySearcher.FindAll()
strFullName = (resultFullName.GetDirectoryEntry.Properties("displayName").Value)
Next
End Sub
With the getUserContactInfo I am gathering the user’s email and phone extension to be saved into the database along with the user’s request for quick easy return contact with the requester. This gets a little different as we use the AD fields a little different when it comes to phone numbers. The Phone Number field in AD we use for DID number and is not real useful for internal work order. Our phone extensions are entered into the Office field and so that is what we are going to query to return the extension of the user in this section.
Sub getUserContactInfo()
' search AD for email address and phone ext for the current user
Dim resultEmail As System.DirectoryServices.SearchResult
mySearcher.Filter = ("(sAMAccountName= " & strUserName & ")")
For Each resultEmail In mySearcher.FindAll()
strEmail = (resultEmail.GetDirectoryEntry.Properties("mail").Value)
Next
Dim resultPhoneExt As System.DirectoryServices.SearchResult
mySearcher.Filter = ("(sAMAccountName= " & strUserName & ")")
For Each resultPhoneExt In mySearcher.FindAll()
strPhoneExt = (resultPhoneExt.GetDirectoryEntry.Properties("physicalDeliveryOfficeName").Value)
Next
End Sub
In the last section, the getWorkstationInfo, I want to know what workstation they were on when they issued the request. This is pretty simple and straight forward on how you gather the workstation name. It comes as a FQDN which I don’t really care for. Since we have only a single namespace, the domain name is worthless to me, so to save space and clean up the look, I strip it off.
Sub getWorkstationInfo()
' set workstation name and trim off domain name
Dim host As System.Net.IPHostEntry
host = System.Net.Dns.GetHostEntry(Request.ServerVariables.Item("REMOTE_HOST"))
strCompName = host.HostName
strCompName = strCompName.Replace(".domainname.com", "")
End Sub
There are many ways to do this and I am not a programmer by any stretch of the imagination, but this works for me. Your mileage may vary on this, but I thought I would throw it out there and maybe it will benefit someone.