Friday, August 17, 2007

Retrieving user email & display name from Team Foundation Server

While working on the continous integration parts in our project TfsBuildLab we needed to resolve a users email based on the accountname retrieved when a checkin notification occurred. My first take was to go straight at the active directory implementing this using LDAP.

However this is some what limiting so I was mucking about and trying to find out how to do it using the TFS api and guess what it isn't that hard at all the following sample illustrates how to do it and at the end of this post I've tried to explain some of the details of the method being used.

using System;
using System.Net;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.Server;

public Identity GetUserInfo(string accountname)
    string tfsUri = "YOURTFSSERVER";
    string tfsUser = "YOURTFSACCOUNT";
    string tfsPassword = "YOURTFSPASSWORD";

    NetworkCredential nc = new NetworkCredential(tfsUser, tfsPassword);

    TeamFoundationServer tfs = new TeamFoundationServer(tfsUri, nc);

    IGroupSecurityService gss = (IGroupSecurityService)tfs.GetService(typeof(IGroupSecurityService));

    Identity identity = gss.ReadIdentity(SearchFactor.AccountName, accountname, QueryMembership.None);

    if (identity != null)
       //how to get the email
       //string email = identity.MailAddress;

       //how to get the displayname
       //string displayname = identity.DisplayName;

       return identity;

    return null;

IGroupSecurityService.ReadIdentity Takes three parameters the first being of the type SearchFactor which lets you specify how you intend to identity the user/group that you which to retrive information about the two most intressting ways (in my oppinion) would be:

SearchFactor.AccountName lets resolve identity based on a windows or tfs identity. The syntax being domain\username or projecturi\groupname

SearchFactor.Sid lets you enter a sid and get back the information about that particular user/user. The syntax being S-1-5-21-1681502023-2202157333-1552196959-1028

The second parameter is where you supply the actual identifier of the type you specified using the SearchFactor.

And the third parameter being of the type QueryMembership is where you specify how groups will be expanded. If you retrieve a group the Identity object you get back contains two member variables called Members (a string array containing the sid's of the members in the returned group empty if it's a not a group) and MemberOf (a string array containing the sid's of the groups the return group/user belongs to). You can specify this in the following way:

QueryMembership.None the quickest way to retrieve the information for a user if you don't need information on which groups he/she belongs to. The aboce mentioned variables Members and MemberOf will be null when using this.

QueryMembership.Direct will not expanded any groups that are members, but simply return the group as one sid.

QueryMembership.Expanded will expand any groups that are members and return the sid's for the contained users in the group.


  1. I'm glad to see you finally cracked this! - Howard

  2. You have no idea how much help this snippet of code was, Thanks.

  3. awesome.... exactly what I was looking for