ProcessTemplate/ProcessTemplate.ps1
<#
.SYNOPSIS Exports a process template definition to disk. .DESCRIPTION This cmdlet offers a functional replacement to the "Export Process Template" feature found in Team Explorer. All files pertaining to the specified process template (work item defininitons, reports, saved queries, process configuration and so on) are downloaded from the given Team Project Collection and saved in a local directory, preserving the directory structure required to later re-import it. This is specially handy to do small changes to a process template or to create a new process template based on an existing one. .PARAMETER Process Name of the process template to be exported. Wildcards supported. .PARAMETER DestinationPath Path to the target directory where the exported process template (and related files) will be saved. .PARAMETER NewName Saves the exported process template with a new name. Useful when exporting a base template which will be used as a basis for a new process template. .PARAMETER NewDescription Saves the exported process template with a new description. Useful when exporting a base template which will be used as a basis for a new process template. .PARAMETER Collection Specifies either a URL/name of the Team Project Collection to connect to, or a previously initialized TfsTeamProjectCollection object. When using a URL, it must be fully qualified. The format of this string is as follows: http[s]://<ComputerName>:<Port>/[<TFS-vDir>/]<CollectionName> Valid values for the Transport segment of the URI are HTTP and HTTPS. If you specify a connection URI with a Transport segment, but do not specify a port, the session is created with standards ports: 80 for HTTP and 443 for HTTPS. To connect to a Team Project Collection by using its name, a TfsConfigurationServer object must be supplied either via -Server argument or via a previous call to the Connect-TfsConfigurationServer cmdlet. For more details, see the Get-TfsTeamProjectCollection cmdlet. .EXAMPLE Export-TfsProcessTemplate -Process 'Scrum' -DestinationPath C:\PT -Collection http://vsalm:8080/tfs/DefaultCollection Exports the Scrum process template from the DefaultCollection project collection in the VSALM server, saving the template files to the C:\PT\Scrum directory in the local computer. .EXAMPLE Export-TfsProcessTemplate -Process 'Scrum' -DestinationPath C:\PT -Collection http://vsalm:8080/tfs/DefaultCollection -NewName 'MyScrum' -NewDescription 'A customized version of the Scrum process template' Exports the Scrum process template from the DefaultCollection project collection in the VSALM server, saving the template files to the C:\PT\MyScrum directory in the local computer. Notice that the process template is being renamed from Scrum to MyScrum, so that it can be later reimported as a new process template instead of overwriting the original one. .INPUTS Microsoft.TeamFoundation.Client.TfsTeamProjectCollection System.String System.Uri #> Function Export-TfsProcessTemplate { [CmdletBinding()] Param ( [Parameter(Position=0)] [SupportsWildcards()] [object] $Process = "*", [Parameter(Mandatory=$true)] [string] $DestinationPath, [Parameter()] [ValidateNotNullOrEmpty()] [string] $NewName, [Parameter()] [ValidateNotNullOrEmpty()] [string] $NewDescription, [Parameter(ValueFromPipeline=$true)] [object] $Collection ) Process { $tpc = Get-TfsTeamProjectCollection $Collection $processTemplateSvc = $tpc.GetService([type]"Microsoft.TeamFoundation.Server.IProcessTemplates") if ($Process -is [Microsoft.TeamFoundation.Server.TemplateHeader]) { $templates = @($Process) } else { $templates = Get-TfsProcessTemplate $Process -Collection $Collection } if ($NewName -or $NewDescription) { $templates = $templates | Select-Object -First 1 } foreach($template in $templates) { if ($NewName) { $templateName = $NewName } else { $templateName = $template.Name } $tempFile = $processTemplateSvc.GetTemplateData($template.TemplateId) $zipFile = "$tempFile.zip" Rename-Item -Path $tempFile -NewName (Split-Path $zipFile -Leaf) $outDir = Join-Path $DestinationPath $templateName New-Item $outDir -ItemType Directory -Force | Out-Null Expand-Archive -Path $zipFile -DestinationPath $outDir if ($NewName -or $NewDescription) { $ptFile = (Join-Path $outDir "ProcessTemplate.xml") $ptXml = [xml] (Get-Content $ptFile) if ($NewName) { $ptXml.ProcessTemplate.metadata.name = $NewName } if ($NewDescription) { $ptXml.ProcessTemplate.metadata.description = $NewDescription } $ptXml.Save($ptFile) } Remove-Item $zipFile } } } <# .SYNOPSIS Gets information from one or more process templates. .PARAMETER Collection Specifies either a URL/name of the Team Project Collection to connect to, or a previously initialized TfsTeamProjectCollection object. When using a URL, it must be fully qualified. The format of this string is as follows: http[s]://<ComputerName>:<Port>/[<TFS-vDir>/]<CollectionName> Valid values for the Transport segment of the URI are HTTP and HTTPS. If you specify a connection URI with a Transport segment, but do not specify a port, the session is created with standards ports: 80 for HTTP and 443 for HTTPS. To connect to a Team Project Collection by using its name, a TfsConfigurationServer object must be supplied either via -Server argument or via a previous call to the Connect-TfsConfigurationServer cmdlet. For more details, see the Get-TfsTeamProjectCollection cmdlet. .INPUTS Microsoft.TeamFoundation.Client.TfsTeamProjectCollection System.String System.Uri #> Function Get-TfsProcessTemplate { [CmdletBinding()] [OutputType('Microsoft.TeamFoundation.Server.TemplateHeader')] Param ( [Parameter(Position=0)] [Alias('Name')] [SupportsWildcards()] [string] $ProcessTemplate = "*", [Parameter(ValueFromPipeline=$true)] [object] $Collection ) Process { $tpc = Get-TfsTeamProjectCollection $Collection $processTemplateSvc = $tpc.GetService([type]"Microsoft.TeamFoundation.Server.IProcessTemplates") $templateHeaders = $processTemplateSvc.TemplateHeaders() | Where-Object Name -Like $ProcessTemplate foreach($templateHeader in $templateHeaders) { $templateHeader | Add-Member Collection $tpc.DisplayName -PassThru } } } <# .SYNOPSIS Imports a process template definition from disk. .PARAMETER Collection Specifies either a URL/name of the Team Project Collection to connect to, or a previously initialized TfsTeamProjectCollection object. When using a URL, it must be fully qualified. The format of this string is as follows: http[s]://<ComputerName>:<Port>/[<TFS-vDir>/]<CollectionName> Valid values for the Transport segment of the URI are HTTP and HTTPS. If you specify a connection URI with a Transport segment, but do not specify a port, the session is created with standards ports: 80 for HTTP and 443 for HTTPS. To connect to a Team Project Collection by using its name, a TfsConfigurationServer object must be supplied either via -Server argument or via a previous call to the Connect-TfsConfigurationServer cmdlet. For more details, see the Get-TfsTeamProjectCollection cmdlet. .INPUTS System.String #> Function Import-TfsProcessTemplate { [CmdletBinding(ConfirmImpact='Medium')] Param ( [Parameter(Position=0, Mandatory=$true, ValueFromPipeline=$true)] [ValidateScript({Test-Path $_ -PathType Container})] [string] $SourcePath, [Parameter()] [ValidateSet("Visible")] [string] $State = "Visible", [Parameter()] [object] $Collection ) Process { if (-Not (Test-Path (Join-Path $SourcePath "ProcessTemplate.xml"))) { throw "Invalid path. Source path ""$SourcePath"" must be a directory and must contain a file named ProcessTemplate.xml." } $tpc = Get-TfsTeamProjectCollection $Collection $processTemplateSvc = $tpc.GetService([type]"Microsoft.TeamFoundation.Server.IProcessTemplates") $tempFile = New-TemporaryFile $zipFile = "$tempFile.zip" Rename-Item $tempFile -NewName (Split-Path $zipFile -Leaf) Compress-Archive -Path "$SourcePath/**" -DestinationPath $zipFile -Force $ptFile = (Join-Path $SourcePath "ProcessTemplate.xml") $ptXml = [xml] (Get-Content $ptFile) $name = $ptXml.ProcessTemplate.metadata.name $description = $ptXml.ProcessTemplate.metadata.description $metadata = $ptXml.ProcessTemplate.metadata.OuterXml $processTemplateSvc.AddUpdateTemplate($name, $description, $metadata, $State, $zipFile); Remove-Item $zipFile } } |