Tuesday, May 31, 2011

Mashup: Team Foundation Server's API and Microsoft Active Directory

I wanted to know the userID and name of anyone that checked out a file in the last 2 months for edit on a specific path inside Tfs. Some of this code was tested to work fine on Tfs2010, but no guarantees.

So it's a nice little bit of code to connect to tfs, get the changes and then pull the names in from active directory with a max of 1 attempt per distinct userID.




//imports: 
//Microsoft.TeamFoundation.Client
//Microsoft.TeamFoundation.VersionControl.Client
//System.DirectoryServices
void Main()
{
 
  Uri tfs08Uri= new Uri("http://tfs.yourtfs.com:8080"); //TODO:this will be specific to your query
  
  
  using(var tfsPc=new TfsTeamProjectCollection(tfs08Uri))
  
  {
  
    var vcs=tfsPc.GetService<Microsoft.TeamFoundation.VersionControl.Client.VersionControlServer>();
   
    var gtpm=vcs.GetItem("$/yourServerPath"); //TODO:this will be specific to your query
    
    
    var pendings=vcs.QueryPendingSets(new[]{gtpm.ServerItem}, RecursionType.Full,null,null);
    var pendingQuery=pendings.Where(p=>p.PendingChanges
        .Any(pc=>pc.CreationDate>DateTime.Today.AddMonths(-2))) 
      .OrderByDescending(p=>p.PendingChanges.Max(d=>d.CreationDate));
      
    var q= from pq in pendingQuery
        from pc in pq.PendingChanges
        where pc.FileName.EndsWith(".refresh")==false
        select new{pq.OwnerName,pq.Computer,pc.ServerItem,pc.CreationDate,pc.FileName};
        var users=q.Select(u=>u.OwnerName).Distinct();
        var joinedQuery= from pc in q
          join l in lookup(users).ToList() on pc.OwnerName equals l.Key into luLeft
          from lu in luLeft.DefaultIfEmpty()
          select new {Name=lu.Value??pc.OwnerName,pc.FileName,pc.ServerItem,pc.CreationDate,pc.Computer,pc.OwnerName};
          joinedQuery.Dump();

        
  
    
  }
}

public static IEnumerable<KeyValuePair<string,string>> lookup(IEnumerable<string> ids)
{


using(var de=new System.DirectoryServices.DirectoryEntry())
{
  var customPath="LDAP://DC=corp,DC=yourdomain,DC=com"; //TODO:this will be specific to your ActiveDirectory
  de.Path=customPath;
  de.AuthenticationType= System.DirectoryServices.AuthenticationTypes.Secure;
  
  using(var deSearch=new System.DirectoryServices.DirectorySearcher())
  {
    deSearch.SearchRoot=de;
    var found=new Dictionary<string,string>( StringComparer.CurrentCultureIgnoreCase);
    foreach(var ownerName in ids)
      {
      if(found.ContainsKey(ownerName))
      yield return  found.First(k=>k.Key==ownerName);
      deSearch.Filter="(&(objectClass=user)(SAMAccountName="+ownerName+"))";
      string value;
      try
      {          
        var me=deSearch.FindOne();  
        value= me.Properties["name"][0].ToString();
        //value.Dump();
      }
      catch(Exception)
      {
        value= null;
      }
       found.Add(ownerName,value);
      yield return new KeyValuePair<string,string>(ownerName,value);
    }
  }
}
}
//references:
//%windir%\Microsoft.Net\Framework\v4.0.30319\System.DirectoryServices.dll
//%ProgramFiles%\Microsoft Visual Studio 10.0\Common7\IDE\ReferenceAssemblies\v2.0\Microsoft.TeamFoundation.Common.dll
//%ProgramFiles%\Microsoft Visual Studio 10.0\Common7\IDE\ReferenceAssemblies\v2.0\Microsoft.TeamFoundation.Client.dll
//%ProgramFiles%\Microsoft Visual Studio 10.0\Common7\IDE\ReferenceAssemblies\v2.0\Microsoft.TeamFoundation.VersionControl.Common.dll
//%ProgramFiles%\Microsoft Visual Studio 10.0\Common7\IDE\ReferenceAssemblies\v2.0\Microsoft.TeamFoundation.VersionControl.Client.dll


Done in LinqPad

Extra snippets/remnants leftover for anyone interested:
//var exclusionList=new [] {"*.suo","*.gpstate","svn","_svn",".svn","*Resharper*"};
    //  vcs.GetItems("$/yourServerSpec/*.suo/", Microsoft.TeamFoundation.VersionControl.Client.RecursionType.Full).Items //TODO: this will be specific to your query
    //    .Select(i=>i.ServerItem).Distinct().Dump();
    //var workspaces=vcs.QueryWorkspaces(null,null,null).Where(w=>w.IsLocal==false & w.LastAccessDate>DateTime.Now.AddDays(-15)).Where(w=>w.Folders.Any(f=> f.ServerItem.StartsWith("$/PST")));
    //workspaces.OrderByDescending(w=>w.LastAccessDate).Dump(1);
//  var checkins=vcs.GetBranchHistory(new ItemSpec[]{new ItemSpec( gtpm.ServerItem, RecursionType.Full)},VersionSpec.Latest);
  //  checkins.Count().Dump();

No comments:

Post a Comment