Adding the current user’s Active Directory displayname to RD Web Access 2012R2


Update (October 24th, 2014): I modified the code slightly to support special characters in the user’s displayname attribute.

This is another addition to the “Customize RD Web Access 2012 R2” series. You can start this series here in case you want to read up or see what else I customized in this series.

This post is inspired by comments in the series, in which readers asked if it was possible to show the logged in user’s displayname as it appears in Active Direcory.
I did a little digging in the code and found a way to accomplish this.

I’m not going to detail the setup I have here. If you’re interested I suggest you read up on the series.

Logging into the RD Web Access shows this:
RDS Customize Web Access - show user displayname 01
This is actually the top of the Default.aspx page.
Just basic stuff here, nothing customized, it shows a basic navigation bar. I’m going to show you how you can add the displayname right after the “Sign out” button on the navigation bar.

The files that make up RD Web Access are in C:\Windows\Web\RDWeb\Pages so make a copy of that folder structure just to make sure we have a backup should we break something.

We are going to use native Windows code from an assembly that is already present on the server that holds the RD Web Access role, but is not known to the RD Web Access application yet. So the first step is to tell the application that we are going to add code.

Open web.config from C:\Windows\Web\RDWeb\Pages in an editor.
Find line 52:
RDS Customize Web Access - show user displayname 02
And add the following code right after that:

<compilation defaultLanguage="c#" debug="true">
  <assemblies>
    <add assembly="System.DirectoryServices, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
  </assemblies>
</compilation>

The result must look like this:
RDS Customize Web Access - show user displayname 03

This tells the RD Web Access application that we need extra code. The extra code is in the .NET Assembly, and specifically in System.DirectoryServices.dll.
Save and close web.config, we don’t need it anymore.

Now open Default.aspx in an editor, which is in C:\Windows\Web\RDWeb\Pages\en-us.
Find line 225:
RDS Customize Web Access - show user displayname 04

Insert the following code before line 225:

private static string GetDisplayName(string strUserName)
{
  string strLDAPPath = "LDAP://dc=itw,dc=test";
  string strFilter = string.Empty;
  
  if(strUserName.Contains("\\")){strUserName = strUserName.Substring(1 + strUserName.IndexOf("\\"));}
  strFilter = "(SAMAccountName=" + strUserName + ")";
  if(strUserName.Contains("@")){strFilter = "(UserPrincipalName=" + strUserName + ")";}
  
  System.DirectoryServices.DirectoryEntry de = new System.DirectoryServices.DirectoryEntry(strLDAPPath);
  System.DirectoryServices.DirectorySearcher ds = new System.DirectoryServices.DirectorySearcher(de);
  ds.Filter = strFilter;
  ds.PropertiesToLoad.Add("DisplayName"); 
  System.DirectoryServices.SearchResultCollection results = ds.FindAll();
  
  return (results != null && results.Count > 0) ? Uri.EscapeDataString(results[0].Properties["DisplayName"][0].ToString()) : string.Empty;
}

Remember to replace “LDAP://dc=itw,dc=test” with your own domain name. So for example, if your domain name is “contoso.local”, this code would be “LDAP://dc=contoso,dc=local”.
The result must look like this (I have wordwrap on in my editor):
2014-10-24_15-09-14
This shows line 225-242 in my file.

Now find line 249:
RDS Customize Web Access - show user displayname 06

And add the following line of code right after that:

userdisplayname="<%=GetDisplayName(strDomainUserName)%>"

The result must look like this:
RDS Customize Web Access - show user displayname 11

This last modification tells the xsl template that it can expect a new variable, and it’s called “userdisplayname”. The value of that variable is the result of the GetDisplayName code you inserted earlier.
Save and close Default.aspx.

Note that if you want to show the displayname on other pages than Default.aspx you need to make these two changes in those files as well! The modifications above in Default.aspx will only work on Default.aspx.

Now open Site.xsl in an editor, which is in C:\Windows\Web\RDWeb\Pages.

Find line 15 (empty line) and insert the following code:

<xsl:variable name="userdisplayname" select="/RDWAPage/@userdisplayname"/>

The result will look like this:
RDS Customize Web Access - show user displayname 08
Here we grab the new variable which we defined in Default.aspx (and now you see why we need to do this on every page that we want to show the displayname on, because the variable is supplied by the actual page).

Find line 323:
RDS Customize Web Access - show user displayname 09

Add the following code on the end of that line:

<xsl:if test="$userdisplayname"> (document.write(decodeURIComponent(''));)</xsl:if>

The result must look like this:
2014-10-24_15-12-38

Save and close Site.xsl.

Open your RD Web Access page, login using valid credentials:
RDS Customize Web Access - show user displayname 12
Or, with special characters:
2014-10-24_15-18-48

Nice! We now have the displayname displayed on the navigation bar, right next to the Sign out button.
I have tested this in my very simple lab setup. I have only one domain, with a single UPN context, so I couldn’t test this with aliases and such.
I have tested this customization using DOMAIN\username, UPN and just username, and that all works.

Till next time,

Arjan

30+ years experience in Microsoft powered environments. Enjoy automating stuff using powershell. In my free time (hah! as if there is any) I used to hunt achievements and gamerscore on anything Xbox Live enabled (Windows Mobile, Windows 8, Windows 10, Xbox 360 and Xbox One). Recently I picked up my Lego addiction again.

Tagged with: , ,
Posted in Customize, Remote Desktop
75 comments on “Adding the current user’s Active Directory displayname to RD Web Access 2012R2
  1. Boris Sirotin says:

    Thanks a lot Arjan. It works as a charm.

  2. David says:

    It is possible to do the same thing if WINDOWS AUTHENTICATION is enabled instead of the Form based?

    • Arjan Mensch says:

      I think it is, but you’d probably need to program that in aspx using c# yourself.
      The way I show you to do it here is based on the cookie and variables that are used throughout your forms based session.
      Time is relatively sparse for me at the moment, but I’ll put it on my list “to find out”.

  3. Andre van den Berg says:

    There is a mistake in the blog, you say that the site.xsl file is in the Language dir but on my system it’s in de Pages dir.

  4. Xa says:

    I keep getting a runtime error each time I modify the changes for the default.aspx file.

  5. Xa says:

    If I ignore everything in the Default.aspx file, and modify everything else in the web.config and site.xsl files, it worked.

    • Ben says:

      XA, did you ever resolve this? I’ve having the same problem. When I insert the code at 225 (script function) I get a runtime error. Any ideas?

      Ben

      • Xa says:

        Ben, I am still getting the runtime error and have not had a chance to look into this further.

      • Arjan Mensch says:

        Ben, XA,
        Sorry for the late reply, was on vacation :)
        Can you check the version of System.DirectoryServices.dll on your Web Access machine?

      • Ben says:

        Arjan,
        I am not sure how to verify the version of this. I tried googling, but could not come up with a method. Please advise.

        Ben

      • Arjan Mensch says:

        Ben,
        Find the dll on your system. It’s probably in C:\Windows\Microsoft.NET somewhere. Check the properties, last tab, file version.

  6. Dean says:

    Like XA if I edit default.aspx I get runtime errors. I have installed Net 3.5 but this did not help! If I dont edit default. all is OK but it does not display anything which defeats the purpose.

  7. Jonathan says:

    Hi, this is good. Can you we do the same thing for Server 2008 R2?

    Thanks

    • Arjan Mensch says:

      Hi Jonathan,
      Sorry for the late reply, was on vacation :)
      I’m sure the same thing can be accomplished on Windows 2008 R2, but not with the steps I provide.
      As my focus is not on Windows 2008 R2 anymore, I cannot help you with this.

  8. omgsone says:

    Hi, I find out that if user’s display contains special characters e.g. “&” this won’t work. Any ideas? Thanks!

    • Arjan Mensch says:

      Hi omgsone,
      Do you get an error? If so, can you mail that to me?

      • omgsone says:

        Hi Arjan,

        Unfortunately I had to switch it back to defaults, as we had a users with special characters on their names. I cannot test that right now, so I don’t have an error messages to give you. However error was from IIS that page cannot be displayed and includes errors. So I mean, after user log in, whole page is invisible.

  9. X2Dojo says:

    I tried this one as well and didn’t work for me. The page gave me an error. I’ll try again in a bit and let you know. thank you.

  10. X2Dojo says:

    Re-tried and double checked and I got a 500 error when opening the page. Double checked everything and still no GO!

  11. X2Dojo says:

    I was able to fix this. Thank you.

    • Arjan Mensch says:

      Hi X2Dojo,
      Glad you were able to fix it. Can you share what was the problem in your situation? Maybe it will help others as well.

      • Rbx774 says:

        I found mismatch in code and result overview:
        ds.PropertiesToLoad.Add(“DisplayNameSystem.DirectoryServices.SearchResultCollection results = ds.FindAll();

        I edit code like in result screeinshot, and it work.
        My version:

        ds.PropertiesToLoad.Add(“DisplayName”);
        System.DirectoryServices.SearchResultCollection results = ds.FindAll();

        return (results != null && results.Count > 0) ? Uri.EscapeDataString(results[0].Properties[“DisplayName”][0].ToString()) : string.Empty;
        }

  12. Joseph Abraham says:

    Hi,

    Can I make RD web access to use my active directory to sign in instead of this form authentication.

    • Arjan Mensch says:

      Hi Joseph,
      If you change the authentication method on the IIS app I think you can.
      Not sure if you also need to modify the authentication section in the web.config though..

  13. Henrik Mai says:

    I think there is a misstake in the Code for the default.aspx on line 225.
    The code as is, didn´t work for me. I correct it into this:

    ds.PropertiesToLoad.Add(“DisplayName”);
    System.DirectoryServices.SearchResultCollection results = ds.FindAll();

    now it works.

  14. omgsone says:

    Yes, current code works, exect if user’s account information includes & or any other special characters.

  15. Patrick says:

    Thanks a lot!

    Since I had a little problem with “document.write” in Firefox, here my solution:

    @site.xsl
    Line 331, change

    to:

    var PORTAL_SIGNOUT = document.getElementById(“PORTAL_SIGNOUT”);
    var DisplayUser = decodeURIComponent(”);

    PORTAL_SIGNOUT.innerHTML = ” (” + DisplayUser + “)”;

    Maybe it es usefull for someone

  16. Rbx774 says:

    I publish my RDS farm through TMG 2010. In Intranet displaying user work correct, but from Internet, user name don’t display. Have any ideas?

    • Arjan Mensch says:

      Hi,
      I think that has to do with whether or not the TMG forwards the original request or not (impersonation?).
      In your case the page tries to find the TMG user instead of the actual user :(

  17. André says:

    hello Arjan,

    I have a couple of domain / forest related questions. and I cannot find them on the internet. do you have time to answer them or show me where I can find the answers?

    Q1. is i possible to have a Windows 2012 R2 RDS vdi implementation and provision Windows 7 VDI machines in another domain?

    Q2. is i possible to have a Windows 2012 R2 RDS vdi implementation and provision Windows 7 VDI machines in another Forest?

    Q3. is i possible to have a Windows 2012 R2 RDS vdi implementation with Windows 7 personal VDI machines in 1 AD/Forest. and have users from another AD/Forest to login and use them?

    Q4. what is the best practises for production environments? having the RDS servers in one domain and the Windows 7 VDI machine in the same or another AD?

    I hope you have some answers,
    Andre

    • Arjan Mensch says:

      Hi André,
      I can only answer Q3 with a definite Yes. Q4: I prefer the same, there’s no best practice really.
      Q1 and Q2 are best found out in a Lab environment, if you really want to know.

  18. Drew Tittle says:

    I was able to get this by following the replies. One thing I ran into is AD accounts without a display name generate an error:

    Index was out of range. Must be non-negative and less than the size of the collection.
    Parameter name: index

    I’m going to take a crack at reverting to no username next to sign in if the display name is null but if you have any hints on how to accomplish it I’d appreciate it. If I figure out a fix I’ll post it.

    • Arjan Mensch says:

      Hi Drew,

      A quick and dirty fix would be to replace the last line in the GetDisplayName function.

      return (results != null && results.Count > 0) ? Uri.EscapeDataString(results[0].Properties[“DisplayName”][0].ToString()) : string.Empty

      Would need to replaced by several lines.
      if (results == null || results.Count < 1) { return ""; }
      strDisplay = Uri.EscapeDataString(results[0].Properties["DisplayName"][0].ToString());
      if (strDisplay == null || strDisplay == String.Empty()) { return "": }
      return strDisplay;

      Now this is without testing and might need some tweaking to get it to work, but something like that would fix your problem.
      That, or just powershell your AD to give everyone a displayname (preferred method actually).

  19. Christian says:

    Hi Arjan,

    First of all thanks for your job its awesome.
    I confirm what Henrik said, there is a mistake in Default.aspx.
    This section:

    ds.PropertiesToLoad.Add(“DisplayNameSystem.DirectoryServices.SearchResultCollection results = ds.FindAll();

    Should be:

    ds.PropertiesToLoad.Add(“DisplayName”);
    System.DirectoryServices.SearchResultCollection results = ds.FindAll();

    I was doin this over and over without any succes then when i tried the following it started to work.
    In order to help others i tought it would be cool to inform you and maybe update you already awesome job :)

    Thanks

    • Arjan Mensch says:

      Hi Christian,
      The code still looks fine in my browser. I tested this with some colleagues, and they notice the errors as well. If you look in the sourcecode of this page, you’ll notice the code is ok there as well. Looks like a wordpress theme issue..

  20. Tommy Gentry says:

    Arjan,

    Your article is great. In my site.xsl the line 323 edit, I did not have that many lines, I had to add in two extra lines just to insert line 323 at the end.

    So my real problem is that I have two web access servers and I’m using microsoft’s NLB between them. The rd web access is accessed by that. when I made the changes in this article above, they apply properly going to each of the local servers. Once you use the NLB name to access the rd web access site, the sign out name does not show.

    is there something else that needs to be added for these changes to show using the NLB name instead of just on the local servers?

    RDWEB1: shows “username (sign out)”
    RDWEB2: shows “username (sign out)”
    RDWEB NLB Name: does not show “username (sign out)”

    • Tommy Gentry says:

      Arjan,

      I just blew away the domain user folder for that user I could not see the signout name with and went to a completely different computer (other than the two test machines I was using) and the username (sign out) showed up internally. also showed externally, thank you!!!!

  21. Digvijay says:

    I am still seeing this :
    Sign out(document.write(decodeURIComponent(”));)

    Is there a way to fix this? I am on Windows 2012R2

    Thanks
    Digvijay

    • Arjan Mensch says:

      Hi Digvijay,
      It looks like WordPress has changed something in how the code is displayed.
      The textversion of the code is missing some pieces :(
      Please refer to my screenshots of my code to fix your problem. In your case it’s the piece of code that is show where it says Find line 323 in this article.
      Sorry for that.

  22. Digvijay says:

    Hi Arjan,
    I followed your suggestion and made the text look exaclty as in the screenshot
    and now line 323 looks like this –

    (document.write(decodeURIComponent(‘xls:value-of select=”$userdisplayname”/>’));)

    However i am not seeing the login name of the user , but this –
    Sign out (xls:value-of select=”$userdisplayname”/>)

  23. Digvijay says:

    Seems like wordpress also changed the text that i entered. But still, my line 323 looks exactly like yours in the screenshot, but i am still unable to get the username displayed correctly.

  24. Igor P says:

    I followed this article to the “T,” but when page loads I get: “Sign Out ()” instead of Sign Out (User Name). Ialready checked everything and all code is exactly like screenshot examples. Where is the mistake?

  25. Igor P says:

    Ok. I think I found solution to my own problem. Not only code displayed on this web page is garbled up by WordPress, but also it seems that code displayed on the last screenshot is wrong is well. I’m not sure why it was necessary to do “document.write(decodeURIComponent”….etc.

    So what I did is replaced this code (see screenshot): https://msfreaks.files.wordpress.com/2014/03/2014-10-24_15-12-38.png

    with this one (see screenshot):

    And everything started to work like it should. I hope it helps someone.

  26. Bhee says:

    Hi Sirs. Can we remove the special character on the user name? example: Logout(Mark%20Anderson).

    Any other wayto remove this special character? appreciate your help.

    Thank you.

    • Daniel Prasanna says:

      Hi How did you remove the special character? I have the same issue. Sign Out (Daniel%20Prasanna)

  27. Andrew Lee says:

    Hi Sir,

    May I know how can I display “Domain\username” instead of displayname?
    Reason being is some of the users sign in with UPN often and they tend to forget their “Domain\username”.
    So I want to display it so that when they need to change password on the RDWeb, they know what is their “Domain\username”

    I’m not a developer, I tried to understand your below coding and see how i can modify but I really can’t figure it out. haha.

    private static string GetDisplayName(string strUserName)
    {
    string strLDAPPath = “LDAP://dc=itw,dc=test”;
    string strFilter = string.Empty;

    if(strUserName.Contains(“\\”)){strUserName = strUserName.Substring(1 + strUserName.IndexOf(“\\”));}
    strFilter = “(SAMAccountName=” + strUserName + “)”;
    if(strUserName.Contains(“@”)){strFilter = “(UserPrincipalName=” + strUserName + “)”;}

    System.DirectoryServices.DirectoryEntry de = new System.DirectoryServices.DirectoryEntry(strLDAPPath);
    System.DirectoryServices.DirectorySearcher ds = new System.DirectoryServices.DirectorySearcher(de);
    ds.Filter = strFilter;
    ds.PropertiesToLoad.Add(“DisplayName”);
    System.DirectoryServices.SearchResultCollection results = ds.FindAll();

    return (results != null && results.Count > 0) ? Uri.EscapeDataString(results[0].Properties[“DisplayName”][0].
    ToString()) : string.Empty;
    }

    Hope to hear from you soon.

    Thanks in advance.

    • Arjan Mensch says:

      Hi Andrew,
      Try replacing “Display Name” with “samAccountName” in the code you quoted.

      • Andrew Lee says:

        Hi Arjan,
        Thanks for the quick response.
        it manage to display the Username But without the domain.
        is it possible to make it display Domain\username?

        I’m thinking maybe we can hard code it somewhere on the following code.
        E.g “contoso” + $userdisplaname (then it will display “contoso\username”)

        (document.write(decodeURIComponent(”));)

  28. James says:

    Is it possible to specify different attributes other than displayName?

    I have tried several from the list of AD attribute names from here: https://www.manageengine.com/products/ad-manager/help/csv-import-management/active-directory-ldap-attributes.html

    However, everytime I save and refresh the page, it throws an exception and won’t load.

    Thanks
    James

    • James says:

      Ignore me, didn’t realise DisplayName was mentioned twice in the code changes on default.aspx

      After changing both to just “name” it works as expected.

  29. John says:

    still getting errors but i will figure it out. really like this ability

  30. John says:

    i tried this a couple times now and i am getting this error

    Index was out of range. Must be non-negative and less than the size of the collection.
    Parameter name: index

  31. John says:

    i worked through with some of the comments to line 238

    Line 238:System.DirectoryServices.SearchResultCollection results = ds.FindAll();

    the compiler errors

    c:\Windows\Web\RDWeb\Pages\en-US\Default.aspx(71,26): warning CS0168: The variable ‘objException’ is declared but never used
    c:\Windows\Web\RDWeb\Pages\en-US\Default.aspx(183,46): warning CS0168: The variable ‘wue’ is declared but never used
    c:\Windows\Web\RDWeb\Pages\en-US\Default.aspx(238,49): error CS0128: A local variable named ‘results’ is already defined in this scope

    thanks john

  32. Jared says:

    I know this is an old thread, but i am trying to get this to work for RDS Web 2016. Everything works the same except that any space or special character is displayed using the ASCII code instead of the space or special character.

    Any ideas how to fix that?

    • dudleydogg says:

      you got this working on 2016 ? what about the line 225 is 245 and that one piece of code breaks RDWEB for me. How did you get around that part?
      and Forms authentication what does that mean is that another method of query to AD ?

  33. Rich L says:

    I can get it working for IE and Chrome, but FireFox does not show the username–just blank

  34. Sami Fantar says:

    Work on 2k19 ! Thank You

  35. vignesh says:

    Hello Arjan,
    I am getiing this error
    CS0120: An object reference is required for the non-static field, method, or property ‘ASP.en_us_default_aspx.LDAPserver’.

    I have configured my ldap in web.config

    But in this line I’m getting the error pls help me asap.
    System.DirectoryServices.DirectoryEntry entry = new System.DirectoryServices.DirectoryEntry(@”LDAP://” + LDAPserver, LDAPid, LDAPpw);

    Thanks
    Vignesh

    • Terry says:

      Hi everyone,

      Has anyone got this to work on Server 2019 or Server 2022? I have a server 2022 setup and it actually got it working. Unfortunately, I did not take a snapshot before I broke it and have not been able to get it back again.

      I seem to be stuck here:

      Server Error in ‘/RDWeb/Pages’ Application.
      The (sAMAccountName=) search filter is invalid.

      LDAP is working properly. Feel free to share any of your config files if you have it working.

      Thanks for any assistance.

Leave a reply to Simon Mousey Smith Cancel reply

Blog Authors
https://paypal.me/ArjanMensch
BTC:1AiAL6QDbfNPiduYYEoy3iNS2m6UKJW2He

Enter your email address to follow this blog and receive notifications of new posts by email.

Join 443 other subscribers
Blog Stats
  • 3,878,515 hits
  • An error has occurred; the feed is probably down. Try again later.
  • An error has occurred; the feed is probably down. Try again later.