TeamProjectCollection/TeamProjectCollection.ps1
<#
.SYNOPSIS Detaches a team project collection database from a Team Foundation Server installation .DESCRIPTION Before you move a collection, you must first detach it from the deployment of TFS on which it is running. It's very important that you not skip this step. When you detach a collection, all jobs and services are stopped, and then the collection database is stopped. In addition, the detach process copies over the collection-specific data from the configuration database and saves it as part of the team project collection database. This configuration data is what allows the collection database to be attached to a different deployment of TFS. If that data is not present, you cannot attach the collection to any deployment of TFS except the one from which it originated. If detachment succeeds, the original database connection string is returned. It is required to re-attach the collection to TFS. .PARAMETER Reason Speficies a Servicing Message (optional), to provide a message for users who might try to connect to projects in this collection .PARAMETER Timeout The maximum period of time this cmdlet should wait for the detach procedure to complete. By default, it waits indefinitely until the collection servicing completes .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/name of the Team Foundation Server to connect to, or a previously initialized TfsConfigurationServer object. When using a URL, it must be fully qualified. The format of this string is as follows: http[s]://<ComputerName>:<Port>/[<TFS-vDir>/] 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.nnTo connect to a Team Foundation Server instance by using its name, it must have been previously registered. .PARAMETER Credential Specifies a user account that has permission to perform this action. The default is the credential of the user under which the PowerShell process is being run - in most cases that corresponds to the user currently logged in.nnType a user name, such as 'User01' or 'Domain01\User01', or enter a PSCredential object, such as one generated by the Get-Credential cmdlet. If you type a user name, you will be prompted for a password.nnTo connect to Visual Studio Team Services you must either: enable Alternate Credentials for your user profile and supply that credential in this argument or omit this argument to have a logon being dialog displayed automatically.nnFor more information on Alternate Credentials for your Visual Studio Team Services account, please refer to https://msdn.microsoft.com/library/dd286572#setup_basic_auth. .INPUTS Microsoft.TeamFoundation.Client.TfsConfigurationServer System.String System.Uri .EXAMPLE Dismount-TfsTeamProjectCollection -Collection http://vsalm:8080/tfs/DefaultCollection -Reason 'Collection DefaultCollecton is down for maintenance' Detaches the project collection specified by the URL provided in the Collection argument, defining a Maintenance Message to be shown to users when they try to connect to that collection while it is detached .LINK https://www.visualstudio.com/en-us/docs/setup-admin/tfs/admin/move-project-collection#1-detach-the-collection .NOTES Detaching a collection prevents users from accessing any projects in that collection #> Function Dismount-TfsTeamProjectCollection { [CmdletBinding(ConfirmImpact="High", SupportsShouldProcess=$true)] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingPlainTextForPassword', '')] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUsePSCredentialType', '')] [OutputType('string')] Param ( [Parameter(Mandatory=$true, Position=0)] [object] $Collection, [Parameter(ValueFromPipeline=$true)] [object] $Server, [Parameter()] [string] $Reason, [Parameter()] [timespan] $Timeout = [timespan]::MaxValue, [Parameter()] [object] $Credential ) Process { $tpc = Get-TfsTeamProjectCollection -Collection $Collection -Server $Server -Credential $Credential if ($PSCmdlet.ShouldProcess($tpc.Name, "Detach Project Collection")) { $configServer = $tpc.ConfigurationServer $tpcService = $configServer.GetService([type] 'Microsoft.TeamFoundation.Framework.Client.ITeamProjectCollectionService') $collectionInfo = $tpcService.GetCollection($tpc.InstanceId) $connectionString = $null $tpcJob = $tpcService.QueueDetachCollection($collectionInfo, $null, $Reason, [ref] $connectionString) $collectionInfo = $tpcService.WaitForCollectionServicingToComplete($tpcJob, $Timeout) return $connectionString } } } <# .SYNOPSIS Gets one or more Team Project Collection addresses registered in the current computer. .PARAMETER Name Specifies the name of a registered collection. When omitted, all registered collections are returned. Wildcards are permitted. .INPUTS System.String #> Function Get-TfsRegisteredTeamProjectCollection { [CmdletBinding()] [OutputType('Microsoft.TeamFoundation.Client.RegisteredProjectCollection[]')] Param ( [Parameter(Position=0, ValueFromPipeline=$true)] [Alias('Name')] [SupportsWildcards()] [string] $Collection = "*" ) Process { $registeredCollections = [Microsoft.TeamFoundation.Client.RegisteredTfsConnections]::GetProjectCollections() foreach($tpc in $registeredCollections) { $tpcName = ([uri]$tpc.Uri).Segments[-1] if($tpcName -like $Collection) { Write-Output $tpc } } } } <# .SYNOPSIS Gets information about one or more team project collections. .DESCRIPTION The Get-TfsTeamProjectCollection cmdlets gets one or more Team Project Collection objects (an instance of Microsoft.TeamFoundation.Client.TfsTeamProjectCollection) from a TFS instance. Team Project Collection objects can either be obtained by providing a fully-qualified URL to the collection or by collection name (in which case a TFS Configuration Server object is required). .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/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. .PARAMETER Current Returns the team project collection specified in the last call to Connect-TfsTeamProjectCollection (i.e. the "current" project collection) .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 .EXAMPLE Get-TfsTeamProjectCollection http:// .INPUTS Microsoft.TeamFoundation.Client.TfsConfigurationServer System.String System.Uri .NOTES Cmdlets in the TfsCmdlets module that operate on a collection level require a TfsConfigurationServer object to be provided via the -Server argument. If absent, it will default to the connection opened by Connect-TfsConfigurationServer. #> Function Get-TfsTeamProjectCollection { [CmdletBinding(DefaultParameterSetName='Get by collection')] [OutputType('Microsoft.TeamFoundation.Client.TfsTeamProjectCollection')] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingPlainTextForPassword', '')] Param ( [Parameter(Position=0, ParameterSetName="Get by collection")] [SupportsWildcards()] [object] $Collection = "*", [Parameter(ValueFromPipeline=$true, ParameterSetName="Get by collection")] [object] $Server, [Parameter(Position=0, ParameterSetName="Get current")] [switch] $Current, [Parameter(ParameterSetName="Get by collection")] [object] $Credential ) Begin { #_ImportRequiredAssembly -AssemblyName 'Microsoft.TeamFoundation.Client' } Process { if (($Current.IsPresent -or (-not $Collection)) -and ($script:TfsTpcConnection)) { return $script:TfsTpcConnection } if ($Collection -is [Microsoft.TeamFoundation.Client.TfsTeamProjectCollection]) { return $Collection } $cred = Get-TfsCredential -Credential $Credential if ($Collection -is [Uri] -or ([Uri]::IsWellFormedUriString($Collection, [UriKind]::Absolute))) { return New-Object Microsoft.TeamFoundation.Client.TfsTeamProjectCollection -ArgumentList ([uri]$Collection), $cred } if ($Collection -is [string]) { $configServer = Get-TfsConfigurationServer -Server $Server -Credential $cred if($configServer) { $filter = [Guid[]] @([Microsoft.TeamFoundation.Framework.Common.CatalogResourceTypes]::ProjectCollection) $collections = $configServer.CatalogNode.QueryChildren($filter, $false, [Microsoft.TeamFoundation.Framework.Common.CatalogQueryOptions]::None) $collections = $collections | Select-Object -ExpandProperty Resource | Where-Object DisplayName -like $Collection foreach ($tpc in $collections) { $collectionId = $tpc.Properties["InstanceId"] Write-Output $configServer.GetTeamProjectCollection($collectionId) } } $registeredCollection = Get-TfsRegisteredTeamProjectCollection $Collection if($registeredCollection.Count) { foreach($tpc in $registeredCollection) { Write-Output (New-Object Microsoft.TeamFoundation.Client.TfsTeamProjectCollection -ArgumentList ([uri]$tpc.Uri), $cred) } return } } } } <# .SYNOPSIS Attaches a team project collection database to a Team Foundation Server installation. .PARAMETER Credential Specifies a user account that has permission to perform this action. The default is the credential of the user under which the PowerShell process is being run - in most cases that corresponds to the user currently logged in.nnType a user name, such as 'User01' or 'Domain01\User01', or enter a PSCredential object, such as one generated by the Get-Credential cmdlet. If you type a user name, you will be prompted for a password.nnTo connect to Visual Studio Team Services you must either: enable Alternate Credentials for your user profile and supply that credential in this argument or omit this argument to have a logon being dialog displayed automatically.nnFor more information on Alternate Credentials for your Visual Studio Team Services account, please refer to https://msdn.microsoft.com/library/dd286572#setup_basic_auth. .INPUTS Microsoft.TeamFoundation.Client.TfsConfigurationServer System.String System.Uri #> Function Mount-TfsTeamProjectCollection { [CmdletBinding(ConfirmImpact='Medium')] Param ( [Parameter(Mandatory=$true, Position=0)] [Alias('Name')] [string] $Collection, [Parameter()] [string] $Description, [Parameter(ParameterSetName="Use database server", Mandatory=$true)] [string] $DatabaseServer, [Parameter(ParameterSetName="Use database server", Mandatory=$true)] [string] $DatabaseName, [Parameter(ParameterSetName="Use connection string", Mandatory=$true)] [string] $ConnectionString, [Parameter()] [ValidateSet("Started", "Stopped")] [string] $InitialState = "Started", [Parameter()] [switch] $Clone, [Parameter()] [int] $PollingInterval = 5, [Parameter()] [timespan] $Timeout = [timespan]::MaxValue, [Parameter(ValueFromPipeline=$true)] [object] $Server, [Parameter()] [System.Management.Automation.Credential()] [System.Management.Automation.PSCredential] $Credential = [System.Management.Automation.PSCredential]::Empty ) Process { $configServer = Get-TfsConfigurationServer $Server -Credential $Credential $tpcService = $configServer.GetService([type] 'Microsoft.TeamFoundation.Framework.Client.ITeamProjectCollectionService') $servicingTokens = New-Object 'System.Collections.Generic.Dictionary[string,string]' if ($DatabaseName) { $servicingTokens["CollectionDatabaseName"] = $DatabaseName } if ($PSCmdlet.ParameterSetName -eq "Use database server") { $ConnectionString = "Data source=$DatabaseServer; Integrated Security=true; Initial Catalog=$DatabaseName" } try { Write-Progress -Id 1 -Activity "Attach team project collection" -Status "Attaching team project collection $Collection" -PercentComplete 0 #$start = Get-Date # string databaseConnectionString, IDictionary<string, string> servicingTokens, bool cloneCollection, string name, string description, string virtualDirectory) $tpcJob = $tpcService.QueueAttachCollection( $ConnectionString, $servicingTokens, $Clone.ToBool(), $Collection, $Description, "~/$Collection/") [void] $tpcService.WaitForCollectionServicingToComplete($tpcJob, $Timeout) return Get-TfsTeamProjectCollection -Server $Server -Credential $Credential -Collection $Collection } finally { Write-Progress -Id 1 -Activity "Attach team project collection" -Completed } throw (New-Object 'System.TimeoutException' -ArgumentList "Operation timed out during creation of team project collection $Collection") } } <# .SYNOPSIS Creates a new team project collection. .PARAMETER Credential Specifies a user account that has permission to perform this action. The default is the credential of the user under which the PowerShell process is being run - in most cases that corresponds to the user currently logged in.nnType a user name, such as 'User01' or 'Domain01\User01', or enter a PSCredential object, such as one generated by the Get-Credential cmdlet. If you type a user name, you will be prompted for a password.nnTo connect to Visual Studio Team Services you must either: enable Alternate Credentials for your user profile and supply that credential in this argument or omit this argument to have a logon being dialog displayed automatically.nnFor more information on Alternate Credentials for your Visual Studio Team Services account, please refer to https://msdn.microsoft.com/library/dd286572#setup_basic_auth. .INPUTS System.String #> Function New-TfsTeamProjectCollection { [CmdletBinding(ConfirmImpact='Medium', SupportsShouldProcess=$true)] [OutputType('Microsoft.TeamFoundation.Client.TfsTeamProjectCollection')] Param ( [Parameter(Mandatory=$true, Position=0, ValueFromPipeline=$true)] [Alias('Name')] [string] $Collection, [Parameter()] [string] $Description, [Parameter(ParameterSetName="Use database server", Mandatory=$true)] [string] $DatabaseServer, [Parameter(ParameterSetName="Use database server")] [string] $DatabaseName, [Parameter(ParameterSetName="Use connection string", Mandatory=$true)] [string] $ConnectionString, [Parameter()] [switch] $Default, [Parameter()] [switch] $UseExistingDatabase, [Parameter()] [ValidateSet("Started", "Stopped")] [string] $InitialState = "Started", [Parameter()] [int] $PollingInterval = 5, [Parameter()] [timespan] $Timeout = [timespan]::MaxValue, [Parameter()] [object] $Server, [Parameter()] [System.Management.Automation.Credential()] [System.Management.Automation.PSCredential] $Credential = [System.Management.Automation.PSCredential]::Empty, [Parameter()] [switch] $Passthru ) Process { if($PSCmdlet.ShouldProcess($Collection, 'Create team project collection')) { $configServer = Get-TfsConfigurationServer $Server -Credential $Credential $tpcService = $configServer.GetService([type] 'Microsoft.TeamFoundation.Framework.Client.ITeamProjectCollectionService') $servicingTokens = New-Object 'System.Collections.Generic.Dictionary[string,string]' $servicingTokens["SharePointAction"] = "None" $servicingTokens["ReportingAction"] = "None" if ($DatabaseName) { $servicingTokens["CollectionDatabaseName"] = $DatabaseName } if ($UseExistingDatabase) { $servicingTokens["UseExistingDatabase"] = $UseExistingDatabase.ToBool() } if ($PSCmdlet.ParameterSetName -eq "Use database server") { $ConnectionString = "Data source=$DatabaseServer; Integrated Security=true" } try { Write-Progress -Id 1 -Activity "Create team project collection" -Status "Creating team project collection $Collection" -PercentComplete 0 $start = Get-Date $tpcJob = $tpcService.QueueCreateCollection( $Collection, $Description, $Default.ToBool(), "~/$Collection/", [Microsoft.TeamFoundation.Framework.Common.TeamFoundationServiceHostStatus] $InitialState, $servicingTokens, $ConnectionString, $null, # Default connection string $null) # Default category connection strings while((Get-Date).Subtract($start) -le $Timeout) { Start-Sleep -Seconds $PollingInterval $collectionInfo = $tpcService.GetCollection($tpcJob.HostId, [Microsoft.TeamFoundation.Framework.Client.ServiceHostFilterFlags]::IncludeAllServicingDetails) $jobDetail = $collectionInfo.ServicingDetails | Where-Object JobId -eq $tpcJob.JobId if (($null -eq $jobDetail) -or (($jobDetail.JobStatus -ne [Microsoft.TeamFoundation.Framework.Client.ServicingJobStatus]::Queued) -and ($jobDetail.JobStatus -ne [Microsoft.TeamFoundation.Framework.Client.ServicingJobStatus]::Running))) { if ($jobDetail.Result -eq [Microsoft.TeamFoundation.Framework.Client.ServicingJobResult]::Failed -or $jobDetail.JobStatus -eq [Microsoft.TeamFoundation.Framework.Client.ServicingJobStatus]::Failed) { throw "Error creating team project collection $Collection : " } $tpc = Get-TfsTeamProjectCollection -Server $Server -Credential $Credential -Collection $Collection if ($Passthru) { return $tpc } } } } finally { Write-Progress -Id 1 -Activity "Create team project collection" -Completed } throw (New-Object 'System.TimeoutException' -ArgumentList "Operation timed out during creation of team project collection $Collection") } } } <# .SYNOPSIS Deletes a team project collection .PARAMETER Credential Specifies a user account that has permission to perform this action. The default is the credential of the user under which the PowerShell process is being run - in most cases that corresponds to the user currently logged in.nnType a user name, such as 'User01' or 'Domain01\User01', or enter a PSCredential object, such as one generated by the Get-Credential cmdlet. If you type a user name, you will be prompted for a password.nnTo connect to Visual Studio Team Services you must either: enable Alternate Credentials for your user profile and supply that credential in this argument or omit this argument to have a logon being dialog displayed automatically.nnFor more information on Alternate Credentials for your Visual Studio Team Services account, please refer to https://msdn.microsoft.com/library/dd286572#setup_basic_auth. .INPUTS Microsoft.TeamFoundation.Client.TfsTeamProjectCollection System.String System.Uri #> Function Remove-TfsTeamProjectCollection { [CmdletBinding(ConfirmImpact="High", SupportsShouldProcess=$true)] Param ( [Parameter(Mandatory=$true, Position=0, ValueFromPipeline=$true)] [object] $Collection, [Parameter()] [object] $Server, [Parameter()] [timespan] $Timeout = [timespan]::MaxValue, [Parameter()] [System.Management.Automation.Credential()] [System.Management.Automation.PSCredential] $Credential = [System.Management.Automation.PSCredential]::Empty ) Process { $tpc = Get-TfsTeamProjectCollection -Collection $Collection -Server $Server -Credential $Credential if ($PSCmdlet.ShouldProcess($tpc.Name, "Delete Team Project Collection")) { Write-Progress -Id 1 -Activity "Delete team project collection" -Status "Deleting $($tpc.Name)" -PercentComplete 0 try { $configServer = $tpc.ConfigurationServer $tpcService = $configServer.GetService([type] 'Microsoft.TeamFoundation.Framework.Client.ITeamProjectCollectionService') $collectionInfo = $tpcService.GetCollection($tpc.InstanceId) $collectionInfo.Delete() } finally { Write-Progress -Id 1 -Activity "Delete team project collection" -Completed } } } } <# .PARAMETER Credential Specifies a user account that has permission to perform this action. The default is the credential of the user under which the PowerShell process is being run - in most cases that corresponds to the user currently logged in.nnType a user name, such as 'User01' or 'Domain01\User01', or enter a PSCredential object, such as one generated by the Get-Credential cmdlet. If you type a user name, you will be prompted for a password.nnTo connect to Visual Studio Team Services you must either: enable Alternate Credentials for your user profile and supply that credential in this argument or omit this argument to have a logon being dialog displayed automatically.nnFor more information on Alternate Credentials for your Visual Studio Team Services account, please refer to https://msdn.microsoft.com/library/dd286572#setup_basic_auth. .INPUTS Microsoft.TeamFoundation.Client.TfsTeamProjectCollection System.String System.Uri #> Function Start-TfsTeamProjectCollection { [CmdletBinding(ConfirmImpact='Medium', SupportsShouldProcess=$true)] Param ( [Parameter(Mandatory=$true, Position=0, ValueFromPipeline=$true)] [object] $Collection, [Parameter()] [object] $Server, [Parameter()] [System.Management.Automation.Credential()] [System.Management.Automation.PSCredential] $Credential = [System.Management.Automation.PSCredential]::Empty ) Process { if($PSCmdlet.ShouldProcess($Collection, 'Start team project collection')) { throw "Not implemented" } } } <# .PARAMETER Credential Specifies a user account that has permission to perform this action. The default is the credential of the user under which the PowerShell process is being run - in most cases that corresponds to the user currently logged in.nnType a user name, such as 'User01' or 'Domain01\User01', or enter a PSCredential object, such as one generated by the Get-Credential cmdlet. If you type a user name, you will be prompted for a password.nnTo connect to Visual Studio Team Services you must either: enable Alternate Credentials for your user profile and supply that credential in this argument or omit this argument to have a logon being dialog displayed automatically.nnFor more information on Alternate Credentials for your Visual Studio Team Services account, please refer to https://msdn.microsoft.com/library/dd286572#setup_basic_auth. .INPUTS Microsoft.TeamFoundation.Client.TfsTeamProjectCollection System.String System.Uri #> Function Stop-TfsTeamProjectCollection { [CmdletBinding(ConfirmImpact='High', SupportsShouldProcess=$true)] Param ( [Parameter(Mandatory=$true, Position=0, ValueFromPipeline=$true)] [object] $Collection, [Parameter()] [string] $Reason, [Parameter()] [object] $Server, [Parameter()] [System.Management.Automation.Credential()] [System.Management.Automation.PSCredential] $Credential = [System.Management.Automation.PSCredential]::Empty ) Process { if($PSCmdlet.ShouldProcess($Collection, 'Stop team project collection')) { throw "Not implemented" } } } |