TeamProject/TeamProject.ps1
<#
.SYNOPSIS Gets information about one or more team projects. .DESCRIPTION The Get-TfsTeamProject cmdlets gets one or more Team Project objects (an instance of Microsoft.TeamFoundation.WorkItemTracking.Client.Project) from the supplied Team Project Collection. .PARAMETER Project Specifies the name of a Team Project. Wildcards are supported. .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. .PARAMETER Server Specifies either a URL or the name of the Team Foundation Server configuration server (the "root" of a TFS installation) to connect to, or a previously initialized Microsoft.TeamFoundation.Client.TfsConfigurationServer object. For more details, see the -Server argument in the Get-TfsTeamProjectCollection cmdlet. .PARAMETER Credential Specifies a user account that has permission to perform this action. The default is the cached credential of the user under which the PowerShell process is being run - in most cases that corresponds to the user currently logged in. To provide a user name and password, and/or to open a input dialog to enter your credentials, call Get-TfsCredential with the appropriate arguments and pass its return to this argument. For more information, refer to https://msdn.microsoft.com/en-us/library/microsoft.teamfoundation.client.tfsclientcredentials.aspx .INPUTS Microsoft.TeamFoundation.Client.TfsTeamProjectCollection System.String System.Uri .NOTES As with most cmdlets in the TfsCmdlets module, this cmdlet requires a TfsTeamProjectCollection object to be provided via the -Collection argument. If absent, it will default to the connection opened by Connect-TfsTeamProjectCollection. #> Function Get-TfsTeamProject { [CmdletBinding(DefaultParameterSetName='Get by project')] [OutputType('Microsoft.TeamFoundation.WorkItemTracking.Client.Project')] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidGlobalVars', '')] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingPlainTextForPassword', '')] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUsePSCredentialType', '')] Param ( [Parameter(Position=0, ParameterSetName='Get by project')] [object] $Project = '*', [Parameter(ValueFromPipeline=$true, Position=1, ParameterSetName='Get by project')] [object] $Collection, [Parameter(Mandatory=$true, ParameterSetName="Get current")] [switch] $Current, [Parameter(ParameterSetName='Get by project')] [object] $Credential ) Begin { #_ImportRequiredAssembly -AssemblyName 'Microsoft.TeamFoundation.WorkItemTracking.Client' } Process { if ($Current) { return $script:TfsProjectConnection } if ($Project -is [Microsoft.TeamFoundation.WorkItemTracking.Client.Project]) { _Log "Input item is of type Microsoft.TeamFoundation.WorkItemTracking.Client.Project; returning input item immediately, without further processing."; return $Project } $tpc = Get-TfsTeamProjectCollection $Collection -Credential $Credential if(_TestGuid $Project) { $Project = [uri] "vstfs:///Classification/TeamProject/$Project" } if (($Project -is [uri]) -or ([System.Uri]::IsWellFormedUriString($Project, [System.UriKind]::Absolute))) { $css = $tpc.GetService([type]'Microsoft.TeamFoundation.Server.ICommonStructureService') $projInfo = $css.GetProject([string] $Project) $Project = $projInfo.Name } if ($Project -is [string]) { $wiStore = $tpc.GetService([type]'Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItemStore') if($Project.IndexOf('*') -ge 0) { return _GetAllProjects $tpc | Where-Object Name -Like $Project | Foreach-Object { $wiStore.Projects[$_.Name] } } return $wiStore.Projects[$Project] } if ($null -eq $Project) { if ($script:TfsProjectConnection) { return $script:TfsProjectConnection } } throw "No TFS team project information available. Either supply a valid -Project argument or use Connect-TfsTeamProject prior to invoking this cmdlet." } } Function _GetAllProjects { param ($tpc) $css = $tpc.GetService([type]'Microsoft.TeamFoundation.Server.ICommonStructureService') return $css.ListAllProjects() | Where-Object Status -eq WellFormed } <# .SYNOPSIS Creates a new team project. #> Function New-TfsTeamProject { [CmdletBinding(DefaultParameterSetName='Get by project',ConfirmImpact='Medium', SupportsShouldProcess=$true)] [OutputType('Microsoft.TeamFoundation.WorkItemTracking.Client.Project')] Param ( [Parameter(Position=0, Mandatory=$true)] [string] $Project, [Parameter(ValueFromPipeline=$true, Position=1)] [object] $Collection, [string] $Description, [string] [ValidateSet('Git', 'TFVC')] $SourceControl, [object] $ProcessTemplate, [Parameter()] [switch] $Passthru ) Process { if($PSCmdlet.ShouldProcess($Project, 'Create team project')) { $tpc = Get-TfsTeamProjectCollection $Collection $template = Get-TfsProcessTemplate -Collection $tpc -Name $ProcessTemplate $client = _GetRestClient 'Microsoft.TeamFoundation.Core.WebApi.ProjectHttpClient' -Collection $tpc $tpInfo = New-Object 'Microsoft.TeamFoundation.Core.WebApi.TeamProject' $tpInfo.Name = $Project $tpInfo.Description = $Description $tpInfo.Capabilities = New-Object 'System.Collections.Generic.Dictionary[[string],System.Collections.Generic.Dictionary[[string],[string]]]' $tpInfo.Capabilities.Add('versioncontrol', (New-Object 'System.Collections.Generic.Dictionary[[string],[string]]')) $tpInfo.Capabilities['versioncontrol'].Add('sourceControlType', $SourceControl) $tpInfo.Capabilities.Add('processTemplate', (New-Object 'System.Collections.Generic.Dictionary[[string],[string]]')) $tpInfo.Capabilities['processTemplate'].Add('templateTypeId', ([xml]$template.Metadata).metadata.version.type) # Trigger the project creation $token = $client.QueueCreateProject($tpInfo).Result if (-not $token) { throw "Error queueing team project creation: $($client.LastResponseContext.Exception.Message)" } # Wait for the operation to complete $operationsClient = _GetRestClient 'Microsoft.VisualStudio.Services.Operations.OperationsHttpClient' -Collection $tpc $opsToken = $operationsClient.GetOperation($token.Id).Result while ( ($opsToken.Status -ne [Microsoft.VisualStudio.Services.Operations.OperationStatus]::Succeeded) -and ($opsToken.Status -ne [Microsoft.VisualStudio.Services.Operations.OperationStatus]::Failed) -and ($opsToken.Status -ne [Microsoft.VisualStudio.Services.Operations.OperationStatus]::Cancelled)) { Start-Sleep -Seconds 2 $opsToken = $operationsClient.GetOperation($token.Id).Result } if ($opsToken.Status -ne [Microsoft.VisualStudio.Services.Operations.OperationStatus]::Succeeded) { throw "Error creating team project $Project" } # Force a metadata cache refresh prior to retrieving the newly created project $wiStore = $tpc.GetService([type]'Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItemStore') $wiStore.RefreshCache() $tp = Get-TfsTeamProject -Project $Project -Collection $Collection if ($Passthru) { return $tp } } } } <# .SYNOPSIS Deletes one or more team projects. .DESCRIPTION .PARAMETER Project Specifies the name of a Team Project. Wildcards are supported. .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. .PARAMETER Credential Specifies a user account that has permission to perform this action. The default is the cached credential of the user under which the PowerShell process is being run - in most cases that corresponds to the user currently logged in. To provide a user name and password, and/or to open a input dialog to enter your credentials, call Get-TfsCredential with the appropriate arguments and pass its return to this argument. For more information, refer to https://msdn.microsoft.com/en-us/library/microsoft.teamfoundation.client.tfsclientcredentials.aspx .INPUTS Microsoft.TeamFoundation.Client.TfsTeamProjectCollection System.String System.Uri .NOTES As with most cmdlets in the TfsCmdlets module, this cmdlet requires a TfsTeamProjectCollection object to be provided via the -Collection argument. If absent, it will default to the connection opened by Connect-TfsTeamProjectCollection. #> Function Remove-TfsTeamProject { [CmdletBinding(SupportsShouldProcess=$true,ConfirmImpact='High')] Param ( [Parameter(Position=0,ValueFromPipeline=$true)] [SupportsWildcards()] [object] $Project, [Parameter()] [object] $Collection, [Parameter()] [switch] $Hard, [Parameter()] [switch] $Force ) Begin { #_ImportRequiredAssembly -AssemblyName 'Microsoft.TeamFoundation.WorkItemTracking.Client' } Process { $tps = Get-TfsTeamProject -Project $Project -Collection $Collection if(-not $tps) { return } foreach($tp in $tps) { $tpc = $tp.TeamProjectCollection $client = _GetRestClient 'Microsoft.TeamFoundation.Core.WebApi.ProjectHttpClient' -Collection $tpc if($PSCmdlet.ShouldProcess($tp.Name, 'Delete team project')) { if((-not $Hard.IsPresent) -or ($Force.IsPresent -or ($PSCmdlet.ShouldContinue('The team project deletion is IRREVERSIBLE and may cause DATA LOSS. Are you sure you want to proceed?')))) { $method = (&{if($Hard.IsPresent) {'Hard'} else {'Soft'}}) _Log "$method-deleting team project $($tp.Name)" $token = $client.QueueDeleteProject($tp.Guid, $Hard.IsPresent).Result if (-not $token) { throw "Error queueing team project deletion: $($client.LastResponseContext.Exception.Message)" } # Wait for the operation to complete $operationsClient = _GetRestClient 'Microsoft.VisualStudio.Services.Operations.OperationsHttpClient' -Collection $tpc $opsToken = $operationsClient.GetOperation($token.Id).Result while ( ($opsToken.Status -ne [Microsoft.VisualStudio.Services.Operations.OperationStatus]::Succeeded) -and ($opsToken.Status -ne [Microsoft.VisualStudio.Services.Operations.OperationStatus]::Failed) -and ($opsToken.Status -ne [Microsoft.VisualStudio.Services.Operations.OperationStatus]::Cancelled)) { _Log "Waiting for the queued operation to finish (current status: $($opsToken.Status))" Start-Sleep -Seconds 1 $opsToken = $operationsClient.GetOperation($token.Id).Result } if ($opsToken.Status -ne [Microsoft.VisualStudio.Services.Operations.OperationStatus]::Succeeded) { _Log "Queued operation finished with status $($opsToken.Status)" throw "Error deleting team project ${Project}: $($opsToken.DetailedMessage)" } } } } } } |