Showing posts with label TFS API. Show all posts
Showing posts with label TFS API. Show all posts

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();
}

Retrieve a list with all your TFS Users

The following code demonstrates how to read all users from different TFS collections.

namespace Migrator
{

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


public static class Helper
{
// without collection name
public static string url = @"http://tfs.yoururl.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("adminuser", "password", "YourDomain");
}

[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;
}

public static List<Identity> GetAllTfsUsers()
{
List<Identity> result = new List<Identity>();
TfsConfigurationServer srv = Helper.GetTfsConfigurationServer();

if (EnsureAuthentication(srv))
{
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);

Console.WriteLine("{0}", tpc.Name);

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

// go over the next node if no projects available
if (workItemStore.Projects.Count <= 0)
{
continue;
}

// iterate over the projects
foreach (Project project in workItemStore.Projects)
{
Console.WriteLine("\tProject: {0}", project.Name);
try
{
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)
{
if (!result.Contains(memberInfo))
{
result.Add(memberInfo);
Console.WriteLine("\t\t" + memberInfo.AccountName + " - " + memberInfo.DisplayName + " - " + memberInfo.Domain);
}
else
{
Console.WriteLine("\t\tUser already available " + memberInfo.AccountName);
}

}
}
}
}
}
}
catch (Exception ex)
{
Console.WriteLine("\tThe Project: '{0}' throws an exception: {1} and will be ignored.", project.Name, ex.Message);
}
} // foreach (Project project in workItemStore.Projects)
} // foreach (CatalogNode tpcNode in tpcNodes)

}
else
{
Console.WriteLine("Authentication problem!");
}

return result;
}



}
}

Friday, April 02, 2010

TFS API: Creating recursive TFS areas

The following code has been founded at Shai Raiten's blog:

TFS API Part 9: Get Area/Iteration Programmatically

TFS API Part 11: Get Area/Iteration Security Settings Using IAuthorizationService

He created a fantastic serie how to work with the API!!!
Thanks Shai



Simple Call:
NodeInfo nodeInfo = this.GetAddNode("\\new area name1", "YourProject", StructureType.Area);
NodeInfo nodeInfo = this.GetAddNode("\\new area name2", "YourProject", StructureType.Area);

Recursive Calls:
NodeInfo nodeInfo = this.GetAddNode("\\new area name\\area 1", "YourProject", StructureType.Area);
NodeInfo nodeInfo = this.GetAddNode("\\new area name\\area 2", "YourProject", StructureType.Area);





public enum StructureType
{
Iteration = 0,
Area = 1
}

private NodeInfo GetAddNode(string ElementPath, string projectName, StructureType nodeType)
{
NodeInfo retVal;
string rootNodePath = "\\" + projectName + "\\" + nodeType.ToString();

//Check if this path already exsist
string newPath = rootNodePath + ElementPath;
try
{
retVal = css.GetNodeFromPath(newPath);
if (retVal != null)
{
// return existing node
return retVal;
}
}
catch (Exception ex)
{
if (ex.Message.Contains("The following node does not exist"))
{
//just means that this path is not exist and we can continue.
}
else
{
throw ex;
}
}

int BackSlashIndex = ElementPath.LastIndexOf("\\");
string Newpathname = ElementPath.Substring(BackSlashIndex + 1);
string NewPath = (BackSlashIndex == 0 ? string.Empty : ElementPath.Substring(0, BackSlashIndex));
string PathRoot = rootNodePath + NewPath;
NodeInfo previousPath = null;
try
{
previousPath = css.GetNodeFromPath(PathRoot);
}
catch (Exception ex)
{
// had to update the string from shai's original code
if (ex.Message.Contains("TF200014: The following node does not exist:"))
{
//just means that this path is not exist and we can continue.
previousPath = null;
}
else
{
throw ex;
}
}
if (previousPath == null)
{
//call this method to create the parent paths.
previousPath = GetAddNode(NewPath, projectName, nodeType);
}

string newPathUri = css.CreateNode(Newpathname, previousPath.Uri);
NodeInfo ni = css.GetNode(newPathUri);

Console.WriteLine("Creating Area: " + ni.Path.ToString());
return ni;
}

TFS API: Get Team Project

The following method retrieves the TeamProject over TFS API:

    private TeamProject GetTeamProject()
{
VersionControlServer versionControl = (VersionControlServer)server.GetService(typeof(VersionControlServer));
TeamProject teamProject = versionControl.GetTeamProject("ProjectName");
return teamProject;
}

TFS API: List all TFS Users

The following code lists all TFS users over the API.

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


    public TfsWrapper()
{
server = new TeamFoundationServer("https://your.tfs.com/tfs/store", GetCredentials());
server.Authenticate();
css = (ICommonStructureService)server.GetService(typeof(ICommonStructureService));
gss = (IGroupSecurityService)server.GetService(typeof(IGroupSecurityService));
tfsIdentities = new List<Identity>();
}


public void ReadTfsUsers()
{
TeamProject tp = this.GetTeamProject();
Identity[] appGroups = gss.ListApplicationGroups(tp.ArtifactUri.AbsoluteUri);

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

if (memberInfo.Type == IdentityType.WindowsUser)
{
if (!this.tfsIdentities.Contains(memberInfo))
this.tfsIdentities.Add(memberInfo);

// Console.WriteLine(" {0}", memberInfo.DisplayName);
//Console.WriteLine("AccountName :" + memberInfo.AccountName);
//Console.WriteLine("Deleted :" + memberInfo.Deleted);
//Console.WriteLine("Description :" + memberInfo.Description);
//Console.WriteLine("DisplayName :" + memberInfo.DisplayName);
//Console.WriteLine("DistinguishedName :" + memberInfo.DistinguishedName);
//Console.WriteLine("Domain :" + memberInfo.Domain);
//Console.WriteLine("MailAddress :" + memberInfo.MailAddress);
//Console.WriteLine("Sid :" + memberInfo.Sid);
//Console.WriteLine("Type :" + memberInfo.Type.ToString());
//Console.WriteLine("*********************************");
}
}
}
}
}
}

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