Copying TFS Work Items

So you want to copy a work item (WI)? Well TFS does indeed have a copy command via the UI which will create a new work item based upon a certain type.

The issue here is that this could be a timely process based upon the number of copies that need to be made. Not to mention the fact that this is a one off process so bulk copying, say 200 WI's (i.e. User Stories) is just not possible.

That said, with a little bit of code and using the Visual Studio Team Foundation Server SDK, it’s possible to harness this functionality to copy a WI as opposed to using the UI. While this code only converts one WI (i.e. User Story -> Task), it’s not a stretch to customize it to iterate through a list of WI’s. As always, a word of caution - use this code at your own risk as using the TFS namespaces directly could severely damage your backlog.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
using System.Net;


namespace workItemConvert


    class ConvertWI


        static int Main(string[] args)


            //Show syntax if no arguments are passed in or user asks for help

            if (args.Length < 3 ||

                args[0].ToLower() == "/h" ||

                args[0].ToLower() == "-h"




                return 1;


            string tfsCollectionURI = args[0];

            string sourceWorkItemID = args[1];

            string targetWorkItemType = args[2];


            ICredentialsProvider provider = new UICredentialsProvider();

            TfsTeamProjectCollection targettfs = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new Uri(tfsCollectionURI), provider);





            catch (Exception e)






            WorkItemStore wis = targettfs.GetService<WorkItemStore>();

            WorkItemCollection wic = wis.Query("SELECT [System.Id] FROM WorkItems WHERE [System.Id] = " + sourceWorkItemID);


            //Detect task work item type

            WorkItemType wiTypeTask = null;

            foreach (WorkItemType wiTypeTemp in wis.Projects[0].WorkItemTypes)


                if (wiTypeTemp.Name.ToLower().Equals(targetWorkItemType))


                    wiTypeTask = wiTypeTemp;





            foreach (WorkItem wi in wic)



                WorkItem copy = wi.Copy(wiTypeTask, WorkItemCopyFlags.CopyFiles | WorkItemCopyFlags.CopyLinks);


                Console.WriteLine("Source ID: {0}  Target ID: {1}", wi.Id, copy.Id);



            return 0;



        private static void showSyntax()


            string thisFileName = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;

            Console.WriteLine("Copies work item to another work item type.");


            Console.WriteLine("Usage: " + thisFileName + " [TFS Collection URL] [Source Work Item ID] [Target Work Item Type]");


            Console.WriteLine("Example: " + thisFileName + " http://MYTFS:8080/tfs/MyProjects 257 Task");


            Console.WriteLine("This example would copy work item ID 257 to a task work item.");






Comments (6)
  1. Jason Haley says:

    Interesting Finds: September 8, 2011

  2. Allen Feinberg says:

    Does this work for Test Case Test Steps and Shared Steps as well?…/86c7e4d4-ca80-463e-b208-ce25850c61ce

  3. Allen~ Yes, any valid work item such as a Bug, Issue, Shared Step, Test Case or User Story can be copied.

  4. Dan Arnell says:

    How do I get the UI you have above and not a command-line?

  5. Dan~ That UI is available via Team Explorer as well as Team Web Access. Here's a link describing this functionality:…/ms181321(v=VS.100).aspx

  6. Bar says:

    I have to write code to bulk copy an epic, feature, story, and/or task list?

    This is ridiculous. Methinks TFS needs to put it’s man-pants on and at least try to offer functionality comparable to what’s been available for years in the marketplace.

Comments are closed.

Skip to main content