Monday, July 19, 2010

assign TFS Workitems to different users

The following code display how it's possible to set the assign-to field from one user to another user. I had to write this code because in my instance the console command did not work:
TFSConfig Identities /change /fromdomain:Contoso1 /todomain:ContosoPrime /account:Contoso1\hholt /toaccount:ContosoPrime\jpeoples

Since the created-by field is a read only field this code will not change the value but if your really need to handle this then I think it should be possible to manipulate the XML of your Workitems and then handle it. Sounds to me like a lot of work.

Add the following using's to your classes:



using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation;
using Microsoft.TeamFoundation.Server;
using Microsoft.TeamFoundation.Framework.Client;
using System.Collections.ObjectModel;
using Microsoft.TeamFoundation.Framework.Common;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
using Microsoft.TeamFoundation.VersionControl.Client;



Helper methods:


public static string url = @"https://tfs.yourdomain.com/tfs";

[System.Diagnostics.DebuggerStepThrough]
public static TfsConfigurationServer GetTfsConfigurationServer()
{
return new TfsConfigurationServer(new Uri(url), GetCredentials(), new UICredentialsProvider());
}

[System.Diagnostics.DebuggerStepThrough]
private static ICredentials GetCredentials()
{
return new NetworkCredential("user", "password", "domain");
}

[System.Diagnostics.DebuggerStepThrough]
public static bool EnsureAuthentication(TfsConfigurationServer srv)
{
bool result = true;

try
{
srv.EnsureAuthenticated();
srv.Authenticate();
result = srv.HasAuthenticated;
}
catch (Exception)
{
result = false;
}

return result;
}


The main code to re-assign your workitem assign-to field over all TFS collections:

this code is stright forward without any add ons or so... enjoy



static void Main(string[] args)
{

List<Identity> tfsIdentities = Helper.GetAllTfsUsers();

Console.WriteLine("Connecting to Server: " + Helper.url);
TfsConfigurationServer srv = Helper.GetTfsConfigurationServer();

Console.WriteLine("Ensure Authenticated: " + Helper.url);
srv.EnsureAuthenticated();

srv.Authenticate();
int counter = 0;

if (srv.HasAuthenticated)
{
CatalogNode configurationServerNode = srv.CatalogNode;

// Query the children of the configuration server node for all of the team project collection nodes
ReadOnlyCollection<CatalogNode> tpcNodes = configurationServerNode.QueryChildren(
new Guid[] { CatalogResourceTypes.ProjectCollection },
false,
CatalogQueryOptions.None);

foreach (CatalogNode tpcNode in tpcNodes)
{
Guid tpcId = new Guid(tpcNode.Resource.Properties["InstanceId"]);
TfsTeamProjectCollection tpc = srv.GetTeamProjectCollection(tpcId);


// Do your tpc work here.
Console.WriteLine("{0}", tpc.Name);



// get a reference to the work item tracking service
var workItemStore = tpc.GetService<WorkItemStore>();

if (workItemStore.Projects.Count <= 0)
{
// go over the next project
continue;
}

// iterate over the projects
foreach (Project project in workItemStore.Projects)
{
Console.WriteLine("\tProject: {0}", project.Name);

VersionControlServer versionControl = (VersionControlServer)tpc.GetService(typeof(VersionControlServer));
TeamProject teamProject = versionControl.GetTeamProject(project.Name);
IGroupSecurityService gss = (IGroupSecurityService)tpc.GetService<IGroupSecurityService>();
Identity[] appGroups = gss.ListApplicationGroups(teamProject.ArtifactUri.AbsoluteUri);

foreach (Identity group in appGroups)
{
Identity[] groupMembers = gss.ReadIdentities(SearchFactor.Sid, new string[] { group.Sid }, QueryMembership.Expanded);
foreach (Identity member in groupMembers)
{
if (member.Members != null)
{
foreach (string memberSid in member.Members)
{
Identity memberInfo = gss.ReadIdentity(SearchFactor.Sid, memberSid, QueryMembership.None);

if (memberInfo.Type == IdentityType.WindowsUser)
{
// Console.WriteLine("\t" + memberInfo.AccountName + " - " + memberInfo.DisplayName + " - " + memberInfo.Domain);
if (!tfsIdentities.Contains(memberInfo))
tfsIdentities.Add(memberInfo);
}
}
}
}
}

WorkItemCollection workItemCollection = workItemStore.Query(
" SELECT [System.Id], [System.WorkItemType]," +
" [System.State], [System.AssignedTo], [System.Title] " +
" FROM WorkItems " +
" WHERE [System.TeamProject] = '" + project.Name +
"' ORDER BY [System.WorkItemType], [System.Id]");

foreach (WorkItem item in workItemCollection)
{
counter++;

bool containsOldDomain = item[CoreField.AssignedTo].ToString().Contains(@"OldValidUser");

if (containsOldDomain)
{
WorkItem item1 = workItemStore.GetWorkItem(item.Id);
item1.Fields[CoreField.AssignedTo].Value = "NewValidUser";

try
{
bool a = (item1.Validate().Count == 0);

if (a)
{
Console.WriteLine("\t\tValid: " + item.Id + item.Title);
item1.Save();
}
else
{
Console.WriteLine("\t\tNot Valid: " + item.Id + item.Title);
}
}
catch (Exception ex)
{
Console.WriteLine(item.Id + ": " + ex.Message);
}
}
}
// clear users
tfsIdentities.Clear();

}
}
}

Console.WriteLine("Workitem count {0}", counter);
Console.WriteLine("Press enter to exit");
Console.ReadLine();
}

No comments:

Shared Cache - .Net Caching made easy

All information about Shared Cache is available here: http://www.sharedcache.com/. Its free and easy to use, we provide all sources at codeplex.

Facebook Badge