AreaIteration/AreaIteration.ps1
Function _GetCssNodes($Node, $Scope, $Project, $Collection) { Process { if ($Node -is [Microsoft.TeamFoundation.Server.NodeInfo]) { _Log "Input item is of type NodeInfo; returning input item immediately, without further processing." return $Node } $tp = Get-TfsTeamProject -Project $Project -Collection $Collection; if (-not $tp -or ($tp.Count -ne 1)) {throw "Invalid or non-existent team project $Project."}; $tpc = $tp.Store.TeamProjectCollection $projectName = $tp.Name $cssService = _GetCssService -Collection $tpc if ($node -is [uri]) { _Log "Getting node by URL [$node]" return $cssService.GetNode($node) } $rootPath = _NormalizeCssNodePath -Project $projectName -Scope $Scope -Path '' -IncludeTeamProject -IncludeScope $rootNodeUri = $cssService.GetNodeFromPath("$rootPath").Uri _Log "Retrieving Nodes XML from root path [$rootPath]" $rootElement = $cssService.GetNodesXml(@($rootNodeUri), $true) $nodePaths = $rootElement.SelectNodes('//@Path') | Select-Object -ExpandProperty '#text' $fullPath = _NormalizeCssNodePath -Project $projectName -Scope $Scope -Path $Node -IncludeScope -IncludeTeamProject -IncludeLeadingBackslash $matchingPaths = $nodePaths | Where-Object { _Log "Evaluating '$_' against pattern '$fullPath' == $($_ -like $fullPath)" -Caller (_GetLogCallStack); $_ -like $fullPath } return $matchingPaths | Foreach-Object { _Log "Returning node from path [$_]" -Caller (_GetLogCallStack); $cssService.GetNodeFromPath($_) } } } Function _DeleteCssNode($Node, $Scope, $MoveToNode, $Project, $Collection) { $tp = Get-TfsTeamProject -Project $Project -Collection $Collection; if (-not $tp -or ($tp.Count -ne 1)) {throw "Invalid or non-existent team project $Project."}; $tpc = $tp.Store.TeamProjectCollection $newNode = _GetCssNodes -Node $MoveToNode -Scope $Scope -Project $Project -Collection $Collection _Log "Moving work items from deleted node [$($Node.Path)] to node [$($newNode.Path)]" $cssService = _GetCssService -Collection $tpc $cssService.DeleteBranches($Node.Uri, $newNode.Uri) } Function _NewCssNode ($Project, $Path, $Scope, $Collection, $StartDate, $FinishDate) { Process { $tp = Get-TfsTeamProject -Project $Project -Collection $Collection; if (-not $tp -or ($tp.Count -ne 1)) {throw "Invalid or non-existent team project $Project."}; $tpc = $tp.Store.TeamProjectCollection $projectName = $tp.Name _Log "Creating $Scope node [$Path] in project $projectName" $cssService = _GetCssService -Collection $tpc try { $fullPath = _NormalizeCssNodePath -Project $projectName -Scope $Scope -Path $Path -IncludeTeamProject -IncludeScope $parentPath = Split-Path $fullPath -Parent $nodeName = Split-Path $fullPath -Leaf $parentNode = $cssService.GetNodeFromPath($parentPath) } catch { _Log "Parent node [$parentPath] does not exist. Creating recursively..." $parentNode = _NewCssNode -Project $Project -Path $parentPath -Scope $Scope -Collection $Collection } if ($StartDate -or $FinishDate) { _Log "Iteration date(s) were provided as Start = [$StartDate], Finish = [$FinishDate]. Creating iteration with supplied dates" $cssService = _GetCssService -Collection $tpc -Version 4 $nodeUri = $cssService.CreateNode($nodeName, $parentNode.Uri, $StartDate, $FinishDate) } else { if($Scope -eq 'Iteration') { _Log "Iteration date(s) were not provided. Creating iteration without dates" } $nodeUri = $cssService.CreateNode($nodeName, $parentNode.Uri) } return $cssService.GetNode($nodeUri) } } Function _NormalizeCssNodePath { Param ( [Parameter(Mandatory=$true)] [string] $Project, [ValidateSet('Area', 'Iteration')] [string] $Scope, [Parameter(Mandatory=$true)] [AllowEmptyString()] [string] $Path, [switch] $IncludeScope, [switch] $ExcludePath, [switch] $IncludeLeadingBackslash, [switch] $IncludeTrailingBackslash, [switch] $IncludeTeamProject ) _Log "Normalizing path '$Path' with arguments $(_DumpObj $PSBoundParameters)" $newPath = '' if ($IncludeLeadingBackslash) { $newPath += '\' } if ($IncludeTeamProject) { $newPath += $Project + '\' } if ($IncludeScope) { $newPath += $Scope + '\' } if(-not $ExcludePath.IsPresent) { $Path = $Path.Trim(' ', '\') if ($Path -like "$Project\$Scope\*") { $Path = $Path.Substring("$Project\$Scope\".Length) } if ($Path -like "$Project\*") { $Path = $Path.Substring($Path.IndexOf('\')) } elseif ($Path -eq $Project) { $Path = '' } $newPath += $Path } if ($newPath.EndsWith('\') -and (-not $IncludeTrailingBackslash.IsPresent)) { $newPath = $newPath.TrimEnd('\') } _Log "Normalized path: $newPath" return $newPath -replace '\\{2,}', '\' } Function _GetCssService($Collection, $Version) { $tpc = Get-TfsTeamProjectCollection -Collection $Collection; if (-not $tpc -or ($tpc.Count -ne 1)) {throw "Invalid or non-existent team project collection $Collection."} return $tpc.GetService([type]"Microsoft.TeamFoundation.Server.ICommonStructureService$Version") } |