User AD Profile Update Page Not Loading Some Properties

Posted on 2016-09-22
Medium Priority
Last Modified: 2016-10-19
I'm using an ASP page written by Bill Boswell (http://download.101com.com/mcp/code/0401UserUpdates.txt). I have it loading on a web server, and have modified it a little to use some drop down menus for users to select from. they should only be able to modify their address, phone number, department & job title. However, when the page loads, it's not displaying some of the users properties correctly.

it looks like distinguishedName is not being pulled correctly, as Logon Name & User Principle Name are not showing up in the table. If I use response.write to display the below, they are all blank.
Response.Write distinguishedName
Response.Write sAMAccountName
Response.Write userPrincipalName
User Updates
However, the other fields, like city, state, job title etc. are being pulled. I couldn't see where the error is! Any suggestions would be appreciated!

Code below:
<%@ Language=VBScript %>
<% 'UserUpdates.asp -- written by Bill Boswell, Bill Boswell Consulting, Inc., www.billboswellconsulting.com
   'This page displays values that users often want to update themselves. 
   'Some of these are "GAL" values -- they appear in the Properties page of a Global Address List entry.
   'Others are not displayed in ADUC so this page is a convenient way to avoid using ADSIEdit. 
   'The script does not handle multiple domains if the domains do not share a contiguous namespace (a "tree").
   'Place this page on an IIS server that support ASP and give Execute rights to the virtual folder. 
   'Remove anonymous authentication from the virtual folder and leave Windows Integrated authentication selected. 
   'The script makes use of passthrough authentication in IIS 5/6 to create instances of ADSI objects,
   'so you'll need to use an IE browser. I'm working on a Firefox/Mozilla version.
   'This script is in the public domain under the Creative Commons. See the end for a link to the declaration.
   'Don't use this code in production until you've tested it thoroughly.    
<meta http-equiv="Content-Language" content="en-au">
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<title>User Information Update Page</title>
<% 'You can modify these styles to match your own system or your webmaster can reference a corporate stylesheet. %>
.dflt { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; font-weight: bold; margin-bottom: 0px; margin-top: 0; color: #000000}
.dflt a:link { color: #000099}
.dflt a:visited { color: #000099}
.note { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 10px; font-weight: normal; margin-bottom: 0px; margin-top: 0; color: #000000}
.notify{ font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; font-weight: bold; margin-bottom: 0px; margin-top: 0; color: #000099}
.prop { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px; font-weight: bold; margin-bottom: 0px; margin-top: 0; color: #000099}
.val  { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; font-weight: bold; margin-bottom: 0px; margin-top: 0; color: #000000}
.valnoADUC  { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; font-weight: normal; margin-bottom: 0px; margin-top: 0; color: #000000}
.colhead { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 15px; font-weight: bold; margin-bottom: 0px; margin-top: 0; color: #FFFFFF}
.pagehead { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 28px; font-weight: bold; margin-bottom: 0px; margin-top: 0; color: #FFFFFF}
.warning { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 14px; font-weight: bold; margin-bottom: 0px; margin-top: 0; color: #000000}

<table align="center" border="3" cellpadding="6" width="600" style="border-collapse: collapse" bordercolor="#000099">
<td align="center" bgcolor="#000099">
<p class="pagehead">User Information Update Page</p>
<td align="center">
<table width="450" border="1"cellspacing="2" cellpadding="4" style="border-collapse: collapse" bordercolor="#000099">
<tr><td class="colhead" align="middle" colspan="5" bgcolor="#000099">Legend</td></tr>
<td class="val" bgcolor="#96fa64">Editable by User</td>
<td class="val" bgcolor="#fafa64">Editable by Admin</td>
<td class="val" bgcolor="#C0C0C0">Not Editable</td>
<td class="val" bgcolor="#fa7d7d">Required</td>
<tr><td colspan="5" align="center">
<p class="note">Values not in bold do not appear </p>
<p class="note">in Active Directory Users and Computers</td></tr>

'Watch out for the ADSystemInfo object. It's handy, but it does not refresh automatically.
'If you move a user to a different container, the user must log out and back on again before using this tool. 
Set adInfo = CreateObject("ADSystemInfo")
Set ntInfo = CreateObject("WinNTSystemInfo")
loggedOnUserDN = adInfo.UserName
loggedOnUserFlatName = ntInfo.UserName

'Specify a DC for creating objects by selecting a DC in the local site using GetAnyDCName
localDC = adInfo.GetAnyDCName

'Check to see if the user is an admin. If so, a selection form will be displayed. 
'If you have a group other than Domain Admins who do user updates, change the group name
Set rootDSE = GetObject("LDAP://" & localDC & "/RootDSE")
domainDN = rootDSE.Get("DefaultNamingContext")
Set daGroup = GetObject("LDAP://" & localDC & "/cn=domain admins,cn=users," & domainDN)
Set adsiUser = GetObject("LDAP://" & localDC & "/" & loggedOnUserDN)
userCN = adsiUser.cn
updatesApplied = vbFalse  'This identifies an initial launch of the page vice a reload after an update.  

'Test to see if the page is being loaded following a form submittal 
'If it's loaded by a Submit, then apply the updates 
userDN = Request.Form("distinguishedName")
If userDN <> "" Then
  Call ProcessUpdates(userDN)  'Apply the updates to Active Directory
  updatesApplied = vbTrue      'Show success notification later in the select form
End If 

'Adminstrators get a form to select users for updates. 
'Users don't see this form. They only see their own information.
If daGroup.ismember("LDAP://" & localDC & "/" & loggedOnUserDN) Then 
  	Response.Write "<form action=userupdates.asp method=get>"
	'Success notification or initial welcome message
	If updatesApplied Then 
		Response.Write "<p class=dflt>Updates successfully applied. Enter another logon name.</p>" 
		Response.Write "<p class=dflt>Welcome " & loggedOnUserFlatName & ". Enter a user logon name.</p>"
  	End If 

    'Build the input form to enter a search name
  	Response.Write "<input type=text size=50 name=searchName>"
  	Response.Write "<input type=submit name=submit value=Submit>"
  	Response.Write "</form>"
  	searchName = Request.QueryString("searchName")
    goodSearch = vbFalse
    If searchName <> "" Then 

      'Perform an ADO search for the samAccountName, the attribute that stores logon name
      'If the search does not succeed, notify and wait for another entry. 
	  Set adoConnection = CreateObject("ADODB.Connection")
  	  adoConnection.Open "Provider = ADsDSOObject"
      srchQry = "Select cn, distinguishedName from 'LDAP://" & domainDN & "' where objectcategory='user' and sAMAccountName='" & searchName & "'"
	  Set rs = adoConnection.Execute(srchQry)
   	  If rs.RecordCount <> 0 Then 
	 	userDN = rs.fields("distinguishedName")
	 	Set adsiUser = GetObject("LDAP://" & userDN)
        goodSearch = vbTrue
      End If 
	  If not goodSearch Then 
	 	Response.Write "<p class=notify>Unable to locate user with that logon name. Try again."
      End If 
    End If 
End If 

'Obtain entries from form submit
'The userDN value was passed in by the form submit 
Public Sub ProcessUpdates(dn)  
  Set adsiUser = GetObject("LDAP://" & dn)
  userCN = adsiUser.cn
  UserPrincipalName = Request.form("newUserPrincipalName")
  streetAddress = Request.Form("newStreetAddress") 
  city = Request.Form("newCity")
  state = request.form("newState")
  zip  = request.form("newZip")
  officeLocation = Request.form("newOfficeLocation")
  title  = request.form("newTitle")
  workPhone  = request.form("newWorkPhone")
  mobile  = request.form("newMobile")
  fax  = request.form("newFax")
  department  = request.form("newDepartment")

'Apply any non-empty entries to associates User attribute
  If UserPrincipalName <> "" then adsiUser.put "UserPrincipalName", UserPrincipalName
  If streetAddress <> "" then adsiUser.put "streetAddress", streetAddress
  If city <> "" then adsiUser.put "L", city
  If state <> "" then adsiUser.put "St", state
  If zip <> "" then adsiUser.put "postalCode", zip
  If officeLocation <> "" then adsiUser.put "PhysicalDeliveryOfficeName", officeLocation
  If title  <> "" then adsiUser.put "Title", title
  If workPhone  <> "" then adsiUser.put "TelephoneNumber", workPhone
  If mobile  <> "" then adsiUser.put "Mobile", mobile
  If fax <> "" then adsiUser.put "FacsimileTelephoneNumber", fax
  If department <> "" then adsiUser.put "Department", department  

'Get ready for possible error
  On Error Resume Next

'Apply the updates. If an error occurs, show it and stop 
'This avoids displaying the form, which would error out because it has no values
  If Err.Number <> 0 Then 
	ShowError Err.Number , Err.Description
  End If 

'Return to default error handling
  On Error Goto 0
End Sub

Sub ShowError(errNum, errMsg)
'Display error message then allow the user to return to the main page
  Response.Write "<p class=pagehead>User Update Failure</p>"
  Response.Write "<p class=warning>An error occurred while updating the account.</p>"
  Response.Write "<p class=warning>Please notify a system administrator with the following error information:</p>"
  Response.Write "<br>"
  Response.Write "<p class=warning>" & err.Number & ": " & Err.Description
  Response.Write "<p>&nbsp;"
  Response.Write "<p class=dflt><a href=userupdates.asp>Return to the User Information Update page.</a></p>"
End Sub



<% 'The form posts to this ASP page. This allows all processing and data collection to reside in one place. %>
<form method="post" action="userupdates.asp" name="collectUserUpdates">
<table align="center" width="600" border="1" cellspacing="2" cellpadding="4" style="border-collapse: collapse" bordercolor="#000099">
<td width="35%" bgcolor="#000099" class="colhead"> Attribute</td>
<td width="35%" bgcolor="#000099" class="colhead"> Current Value</td>
<td width="35%" bgcolor="#000099" class="colhead"> New Value</td>

<% 'Translating the ADSI values to friendly name is something of a chore
   'Most of the properties are included in the Personal Property Set to simplify permission assignment
   'If you want the user to change Title or Department, you'll need to assign specific permissions
   'None of these entries are validated. Either train the users well or add your own validation codes.%>
<% With adsiUser  %>
 <%= "<tr><td  class=prop>Logon Name</td><td class=val  bgcolor=#C0C0C0>" & .SamAccountName &  "</td><td></td></tr>" &vbCr %>
 <%= "<tr><td  class=prop>User Principal Name</td><td class=val  bgcolor=#C0C0C0>" & .UserPrincipalName &  "</td><td></td></tr>" &vbCr %>
 <%= "<tr><td  class=prop>Street Address</td><td class=val bgcolor=#96fa64>" & .streetAddress &  "</td><td><input type=text length=120 maxlength=200 name=newStreetAddress ></td></tr>" &vbCr %>
 <%= "<tr><td  class=prop>City</td><td class=val bgcolor=#96fa64>" & .L &  "</td><td><input type=text length=120 maxlength=200 name=newCity ></td></tr>" &vbCr %>
 <%= "<tr><td  class=prop>State</td><td class=val bgcolor=#96fa64>" & .St &  "</td><td><input type=text length=120 maxlength=200 name=newState ></td></tr>" &vbCr %>
 <%= "<tr><td  class=prop>Post Code</td><td class=val bgcolor=#96fa64>" & .PostalCode &  "</td><td><input type=text length=120 maxlength=200 name=newZip ></td></tr>" &vbCr %>
 <%= "<tr><td  class=prop>Office Location</td><td class=val bgcolor=#96fa64>" & .PhysicalDeliveryOfficeName &  "</td><td><input type=text length=120 maxlength=200 name=newOfficeLocation ></td></tr>" &vbCr %>
 <%= "<tr><td  class=prop>Job Title*</td><td class=val bgcolor=#fa7d7d>" & .Title &  "</td><td><input type=text length=120 maxlength=200 name=newTitle ></td></tr>" &vbCr %>
 <%= "<tr><td  class=prop>Department*</td><td class=val bgcolor=#fa7d7d>" & .Department &  "</td><td><SELECT NAME=newDepartment><OPTION VALUE='"& .Department &"' SELECTED>"& .Department & vbCr %>
<OPTION VALUE=Finance>Finance
<OPTION VALUE=Quality>Quality
<OPTION VALUE=Operations>Operations
<OPTION VALUE=General Management>General Management
<OPTION VALUE=Quality Assurance>Quality Assurance
<OPTION VALUE=Warehouse>Warehouse
<OPTION VALUE=Validation>Validation
<OPTION VALUE=Human Resources>Human Resources
<OPTION VALUE=Business Development>Business Development
<OPTION VALUE=Finance>Finance
<OPTION VALUE=Project Management>Project Management
<OPTION VALUE=Engineering>Engineering
<OPTION VALUE=Procurement>Procurement
<OPTION VALUE=Administration>Administration
<OPTION VALUE=Manufacturing>Manufacturing
<OPTION VALUE=Supply Chain>Supply Chain
<OPTION VALUE=Maintenance>Maintenance
<OPTION VALUE=Environmental Health & Safety>Environmental Health & Safety
<OPTION VALUE=Information Technology>Information Technology
<OPTION VALUE=Marketing>Marketing
<OPTION VALUE=Account Mgmt>Account Mgmt
<OPTION VALUE=(PLS) Lab Services>(PLS) Lab Services
<OPTION VALUE=Technical & R&D>Technical & R&D
<OPTION VALUE=Operational Excellence>Operational Excellence
<OPTION VALUE=Production Planning>Production Planning
<OPTION VALUE=Formulation>Formulation
<OPTION VALUE=Scientific>Scientific
<OPTION VALUE=Facilities>Facilities
<OPTION VALUE=Packaging Administration>Packaging Administration
<OPTION VALUE=Corporate Development>Corporate Development
<OPTION VALUE=Strategy>Strategy
 <%= "<tr><td  class=prop>Work Phone No.*²</td><td class=val bgcolor=#fa7d7d>" & .TelephoneNumber &  "</td><td><input type=text length=120 maxlength=200 name=newWorkPhone ></td></tr>" &vbCr %>
 <%= "<tr><td  class=prop>Work Mobile No.*²</td><td class=val bgcolor=#fa7d7d>" & .Mobile &  "</td><td><input type=text length=120 maxlength=200 name=newMobile ></td></tr>" &vbCr %>
 <%= "<tr><td  class=prop>Work Fax No.</td><td class=val bgcolor=#96fa64>" & .FacsimileTelephoneNumber &  "</td><td><input type=text length=120 maxlength=200 name=newFax ></td></tr>" &vbCr %>
 <% 'Include the user's DN in the form to allow an admin to update someone else's information. %>
 <%= "<input type=hidden name=userDistinguishedName value=""" & .DistinguishedName & """>" %>
  <%End With%>
<% 'I put the submit button at the bottom of the form, which might look a little inconvenient. 
   'However, the user can press Enter at any point in the form to submit the updates. %>
<tr><td colspan="3" align="center"><input type="submit" name="updateUserInfo" value="Update User Information"></td></tr>

<p align="left" class=prop>*=Required Field</p>

Open in new window

Question by:bjblackmore
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
LVL 30

Expert Comment

by:Randy Downs
ID: 41812587
Does it work if you are an admin?

It looks like it was setup for passthrough authentication so you probably need to update something like this .

add 'Users' to the permissions. Set up IIS just like you have with NTLM as the top provider, Windows Authentication only enabled (you can get rid of the section in the web.config, all you need is <authentication="Windows" />) and add IIS_USRS and Users to the permission set.

Accepted Solution

bjblackmore earned 0 total points
ID: 41827671
Sorry for the delay in replying. No it doesn't work if you're an admin either.

I checked IIS setup, and those security settings were already in place.

i think I have a better way of doing this, using a VB application I'm writing rather than a web site. Website would have been nice, as it's just as single page for everyone. But the app looks better, just means we have to deploy a small 100kb exe to all desktops & laptops.

Author Closing Comment

ID: 41849712
I have written an app in Visual Basic that does everything needed

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

A company’s centralized system that manages user data, security, and distributed resources is often a focus of criminal attention. Active Directory (AD) is no exception. In truth, it’s even more likely to be targeted due to the number of companies …
Microsoft Office 365 is a subscriptions based service which includes services like Exchange Online and Skype for business Online. These services integrate with Microsoft's online version of Active Directory called Azure Active Directory.
This video shows how to use Hyena, from SystemTools Software, to bulk import 100 user accounts from an external text file. View in 1080p for best video quality.
Are you ready to implement Active Directory best practices without reading 300+ pages? You're in luck. In this webinar hosted by Skyport Systems, you gain insight into Microsoft's latest comprehensive guide, with tips on the best and easiest way…
Suggested Courses

801 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question