15

I would like to make a copy of a work item and all of its task.

I'm using this version of the product: 11.0.50727.1 I'm using Scrum 2.0 template for the project

If this is possible, how can I do it?

jessehouwing
  • 106,458
  • 22
  • 256
  • 341
Fernando Moyano
  • 1,097
  • 4
  • 15
  • 29

2 Answers2

13

Have you tried Excel? It's your best friend when doing mass editing of work items. You can copy/paste a number of work items. by selecting all columns except the ID column. Copy them and then paste them at the bottom of the open query in Excel.

You need to ensure you're using a Tree based query and that all the columns you want to duplicate are part of the queries columns.

You might lose formatting of HTML typed fields this way though.

I'd be interested to know why you'd want to bulk copy Product Backlog items with all their tasks, from a scrum perspective I don't really see how it would make sense.

jessehouwing
  • 106,458
  • 22
  • 256
  • 341
  • 2
    I wonder if he's splitting iterations, or moving incomplete items from one iteration to the next? – John Saunders Jan 29 '13 at 19:14
  • @JohnSaunders, that's my guess as well... But that shouldn't happen so often to want to have a feature for it ;). I wouldn't expect the same work in two iterations, unless it's "Build feature", "Design Feature", "Test Feature", "Deploy Feature" each and every time, in which case the tasks don't make much sense. – jessehouwing Jan 29 '13 at 19:31
  • Thanks, to all of you. I will try the Excel option, honestly, I've done that once and never used again so you remind me that again. About your question, in our business, you can model a user history using a predefined subset of tasks, we have that working fine in our development tool, and that is why I need to repeat the same number of tasks. I'm not splitting iterations, and I did have to move itemos from one iteration to the next, but just did it updating the iteration field. – Fernando Moyano Jan 29 '13 at 19:59
  • 3
    Copying tasks can also be helpful for capturing release steps so that you have a consistent, repeatable process. It's too bad this is still so hard. DRY is for code. Repeatability is important for other parts of our world! – Jaime Jul 29 '16 at 14:42
13

I see by the date this question is a little more than 2 years old. Excel would not create the parent links for me. Here is my Powershell solution:

if ( (Get-PSSnapin -Name Microsoft.TeamFoundation.PowerShell -ErrorAction SilentlyContinue) -eq $null )
{
     Add-PSSnapin Microsoft.TeamFoundation.PowerShell
}

[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.TeamFoundation.Client")
[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.TeamFoundation.Build.Client")
[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.TeamFoundation.Build.Common")
[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.TeamFoundation.WorkItemTracking.Client")

# Connect to TFS and get Work Item Store.
$tfsCollectionUrl = "https://tfs.CORP.com/tfs/group"
$tfs = Get-TfsServer -name $tfsCollectionUrl
$ws = $tfs.GetService([type]"Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItemStore")

$storyID = 15211    # ID of the story you want to copy.

$story = $ws.GetWorkItem($storyID)
Write-Host "Cloning User Story: " + $story.Title

#Clone User Story
$cloneStory = $story.Copy()
($story, $cloneStory )
$cloneStory.Title = "COPY : " + $story.Title

# cloneStory will not have links to all the tasks that were linked to the orginal story.
# cloneStory will have two links, one to the same "feature" that the orginal was linked to, and one to the story it was cloned from.
$cloneStory.Links

# cloneStory will have 0 for an ID, because it has not yet been saved.
$cloneStory.Id
#$cloneStory.Save()
# cloneStory will now have an ID.
$cloneStory.Id
$parentID = $cloneStory.Id  # Parent ID will be used to link new cloned tasks to this story.

$links = $story.Links

# Define a Link Type to be used in the loop.
$linkType = $ws.WorkItemLinkTypes[[Microsoft.TeamFoundation.WorkItemTracking.Client.CoreLinkTypeReferenceNames]::Hierarchy]


foreach ( $link in $links )
{

    $itemID = $link.RelatedWorkItemId
    #$itemID

    $item = $ws.GetWorkItem($itemID)

    if ( ($item.Type).Name -eq "Task" )
    {
        $reportLine = "Cloning Task ID:{0} {1}" -f $itemId, $item.Title
        Write-Host $reportLine
        # Clone the Task
        # Create the Parent Link object
        # Add the Parent Link to Cloned Task
        # Save New Cloned Task

        $cloneTask = $item.Copy()
        $cloneTask.Title = "COPY : " + $item.Title
        $parentLink = new-object Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItemLink($linkType.ReverseEnd, $parentID)
        $cloneTask.WorkItemLinks.Add($parentLink)
        $cloneTask.save()
        $cloneTask
    }
    else
    {
        $reportLine = "Skipping: {0} is not a Task, it is a {1}" -f $item.Title, ($item.Type).Name
        Write-Host $reportLine
    }
}
Joe B
  • 692
  • 8
  • 18