TFVC.psm1
using namespace Microsoft.TeamFoundation.Client using namespace Microsoft.TeamFoundation.VersionControl.Client using namespace Microsoft.TeamFoundation.VersionControl.Common using namespace system $Script:PSModuleRoot = $PSScriptRoot # .C:\ldx\tfvc\TFVC\Classes\TFVCSession.ps1 class TFVCSession { [uri] $DisplayName [uri] $Server hidden [PSCredential] $Credential hidden [TfsTeamProjectCollection] $TfsTeamProjectCollection hidden [VersionControlServer] $VersionControlServer TFVCSession( [uri]$ProjectCollectionURI ) { $this.Connect( $ProjectCollectionURI ) } TFVCSession( [uri]$ProjectCollectionURI, [PSCredential]$Credential ) { $this.Connect( $ProjectCollectionURI, $Credential ) } TFVCSession( [uri]$Server, [string]$ProjectCollectionName ) { $URI = [uribuilder]::new( $Server) $URI.Path = $ProjectCollectionName $this.Connect( $URI.uri ) } TFVCSession( [uri]$Server, [string]$ProjectCollectionName, [PSCredential]$Credential ) { $URI = [uribuilder]::new( $Server) $URI.Path = $ProjectCollectionName $this.Connect( $URI.uri, $Credential ) } [Void] Connect( [uri]$ProjectCollectionURI ) { $this.TfsTeamProjectCollection = [TfsTeamProjectCollection]::new( $ProjectCollectionURI ) $this.ValidateConnection($ProjectCollectionURI) $this.RefreshProperties() } [Void] Connect( [uri]$ProjectCollectionURI, [PSCredential]$Credential ) { $this.TfsTeamProjectCollection = [TfsTeamProjectCollection]::new( $ProjectCollectionURI, $Credential ) $this.TfsTeamProjectCollection.Credentials = $Credential $this.ValidateConnection($ProjectCollectionURI) $this.RefreshProperties() } [Void] ValidateConnection([uri] $uri) { if ( $null -eq $this.TfsTeamProjectCollection.ConfigurationServer ) { throw [TFVCSessionException]::New("Was not able to establish a connection to the specified endpoint [$uri]") } } [Void] RefreshProperties() { if ( $null -ne $this.TfsTeamProjectCollection ) { $this.DisplayName = $this.TfsTeamProjectCollection.DisplayName $this.Server = $this.TfsTeamProjectCollection.ConfigurationServer.Uri $this.VersionControlServer = $this.GetVersionControlServer() } } [Void] Disconnect() { if ($null -ne $this.TfsTeamProjectCollection) { $this.TfsTeamProjectCollection.Disconnect() $this.TfsTeamProjectCollection.Dispose() $this.TfsTeamProjectCollection = $null } } hidden [VersionControlServer] GetVersionControlServer () { return $this.TfsTeamProjectCollection.GetService( [VersionControlServer] ) } [Workspace] GetWorkspaceFromPath( $LocalPath ) { return $this.VersionControlServer.GetWorkspace( $LocalPath ) } [Workspace] GetWorkspace( $WorkspaceName, $WorkspaceOwner ) { return $this.VersionControlServer.GetWorkspace( $WorkspaceName, $WorkspaceOwner ) } [Workspace] CreateWorkspace( $Name ) { return $this.VersionControlServer.CreateWorkspace( $Name ) } [Shelveset] CreateShelveset( [string]$Name ) { return [Shelveset]::new( $this.VersionControlServer, $Name, $ENV:USERNAME ) } [Changeset] GetChangeset( [Int32]$ChangesetID, [bool]$IncludeChanges, [bool]$IncludeDownloadInfo ) { return $this.VersionControlServer.GetChangeset( $ChangesetID, $IncludeChanges, $IncludeDownloadInfo ) } [Void] DownloadFile( [string]$ServerPath, [string]$DestinationPath ) { $folder = Split-Path $DestinationPath New-Item -Path $folder -ItemType Directory -Force -ErrorAction Ignore $this.VersionControlServer.DownloadFile( $ServerPath, $DestinationPath ) } [Changeset[]] GetHistory ( [String] $ServerPath, [String] $User, [Int32] $MaxCount, [Boolean] $IncludeChanges, [Boolean] $SortAscending ) { [Int32] $DeletionId = 0 [VersionSpec] $Version = [VersionSpec]::Latest [RecursionType] $Recursion = [RecursionType]::Full [VersionSpec] $VersionFrom = $null [VersionSpec] $VersionTo = $null [Boolean] $SlotMode = $true [Boolean] $IncludeDownloadInfo = $true if ( [string]::IsNullOrEmpty( $User ) ) { $User = [NullString]::Value } return $this.VersionControlServer.QueryHistory( $ServerPath, $Version, $DeletionId, $Recursion, $User, $VersionFrom, $VersionTo, $MaxCount, $IncludeChanges, $SlotMode, $IncludeDownloadInfo, $SortAscending ) } } # .C:\ldx\tfvc\TFVC\Classes\TFVCSessionException.ps1 class TFVCSessionException : Exception { TFVCSessionException() {} TFVCSessionException( [string] $Message ) : base( $message ) {} TFVCSessionException( [string] $Message, [exception] $Inner ) : base( $Message, $Inner ) {} } # Importing from [C:\ldx\tfvc\TFVC\Private] # Importing from [C:\ldx\tfvc\TFVC\Public] # .\TFVC\Public\Add-TFVCItem.ps1 function Add-TFVCItem { <# .Synopsis Adds items to the workspace that will become pending changes .Example Add-TFVCItem -Path $Path .Notes #> [Alias('TFAdd')] [cmdletbinding()] param( # Path to the file to add. Supports wildcards [Parameter( Position = 0, ValueFromPipelineByPropertyName )] [ValidateNotNullOrEmpty()] [String[]] $Path = '.', # Recursivly add files [Parameter( Position = 1, ValueFromPipelineByPropertyName )] [switch] $Recurse, # The Workspace [Parameter( Position = 2, ValueFromPipeline )] [Workspace] $Workspace = (Get-TFVCActiveWorkspace) ) process { try { $allFiles = Resolve-Path -Path $Path $count = foreach ( $node in $allFiles.Path ) { $Workspace.PendAdd( $node, $Recurse ) } [PSCustomobject]@{ LocalItems = $allFiles NumberAdded = $count } } catch { $PSCmdlet.ThrowTerminatingError( $PSItem ) } } } # .\TFVC\Public\Add-TFVCWorkspaceMapping.ps1 function Add-TFVCWorkspaceMapping { <# .Synopsis Adds a source to folder mapping to the workspace .Example New-TFVCSession -ServerURI https://tfs -ProjectCollection DevOps $workspace = Get-TFVCWorkspace $workspace | Add-TFVCWorkspaceMapping -Source '$/DevOpsTFVCTest/master' -Destination 'c:\localworkspace\DevOpsTFVCTest\master' .Notes #> [Alias('TFMap')] [cmdletbinding( DefaultParameterSetName = 'Path', SupportsShouldProcess )] param( # A workspace to add a source mapping to [Parameter( ValueFromPipeline )] [ValidateNotNullOrEmpty()] [Workspace] $Workspace = (Get-TFVCActiveWorkspace), # The TFS locaion to map to the local system [Alias('SourcePath', 'TFSLocaion', 'ServerItem')] [Parameter( Mandatory, Position = 0, ValueFromPipelineByPropertyName, ParameterSetName = 'Path' )] [ValidateNotNullOrEmpty()] [String] $Source, # The location on the local system that gets mapped [Alias('DestinationPath', 'Path', 'LocalPath', 'FullName', 'LocalItem')] [Parameter( Mandatory, Position = 1, ValueFromPipelineByPropertyName, ParameterSetName = 'Path' )] [ValidateNotNullOrEmpty()] [String] $Destination, # The location on the local system that gets mapped [Alias('WorkingFolder')] [Parameter( Mandatory, Position = 0, ValueFromPipeline, ParameterSetName = 'WorkingFolder' )] [ValidateNotNullOrEmpty()] [WorkingFolder] $Mapping ) process { try { if ( $null -ne $Mapping ) { $Source = $Mapping.ServerItem $Destination = $Mapping.LocalItem } # normalize to full path $null = New-Item -Path $Destination -ItemType Directory -Force -ErrorAction Ignore $Destination = Resolve-Path -Path $Destination Write-Verbose ( "Mapping source [{0}] to local [{1}] in workspace [{2}]" -f $Source, $Destination, $Workspace.DisplayName ) # Check to see if it is already mapped $currentFolder = $Workspace.Folders | Where ServerItem -eq $Source Where LocalItem -eq $Destination if ( $null -eq $currentFolder ) { Write-Verbose ' Adding new mapping' if ( $PSCmdlet.ShouldProcess( $Source ) ) { if ( $null -ne $Mapping ) { $Workspace.CreateMapping( $Mapping ) } else { $Workspace.Map( $Source, $Destination ) } Write-Verbose ' Verify working folder was created' $Workspace.GetWorkingFolderForServerItem( $Source ) } } else { Write-Verbose " Folder [$Destination] is already mapped in this workspace" $currentFolder } } catch { $PSCmdlet.ThrowTerminatingError( $PSItem ) } } } # .\TFVC\Public\Get-TFVCActiveWorkspace.ps1 function Get-TFVCActiveWorkspace { <# .Synopsis Gets the currently active workspace .Example Get-TFVCActiveWorkspace .Notes This is used to provide a default value for cmdlets that need a workspace. This is why it throws an error if it is used before a workspace is set. #> [cmdletbinding(SupportsShouldProcess)] param() end { if ( $PSCmdlet.ShouldProcess( $script:ActiveTFVCWorkspace.DisplayName ) ) { if ( $script:ActiveTFVCWorkspace ) { $script:ActiveTFVCWorkspace } else { Write-Error -ErrorAction Stop -ErrorId NoActiveTFVCWorkspace -Message 'No active workspace is set. Please provide a workspace or set an active one using Set-TFVCActiveWorkspace.' } } } } # .\TFVC\Public\Get-TFVCChangeset.ps1 function Get-TFVCChangeset { <# .Synopsis Get specified changeset details .Example Get-TFVCChangeset -ChangesetID $ChangesetID .Notes GetChangeSet: https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2013/ff737622%28v%3dvs.120%29 Changeset: https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2013/bb170151%28v%3dvs.120%29 #> [Alias('TFChangeset')] [CmdletBinding()] [Outputtype('[Microsoft.TeamFoundation.VersionControl.Client.Changeset]')] param( # The ID of the Changeset. [Parameter( Mandatory, Position = 0, ValueFromPipelineByPropertyName )] [ValidateNotNullOrEmpty()] [Int32[]] $ChangesetID, # Active TFVC Session [Parameter()] [ValidateNotNullOrEmpty()] [TFVCSession] $TFVCSession = (Get-TFVCSession), # True to include the changes in the Changeset. False to include only metadata. [Parameter()] [switch] $IncludeChanges, # True to get the information needed to download files. Specify false to save bandwidth if not necessary. [Parameter()] [switch] $IncludeDownloadInfo ) process { try { foreach ( $id in $ChangesetID ) { $TFVCSession.GetChangeset( $id, $IncludeChanges, $IncludeDownloadInfo ) } } catch { $PSCmdlet.ThrowTerminatingError( $PSItem ) } } } # .\TFVC\Public\Get-TFVCFile.ps1 function Get-TFVCFile { <# .Synopsis Downloads a file from the TFS server .Example Get-TFVCFile -ServerPath $ServerPath -Path $Path .Notes #> [Alias('TFDownload')] [cmdletbinding(SupportsShouldProcess)] param( # Server location for the file to download [Alias('Source')] [Parameter( Mandatory, Position = 0, ValueFromPipelineByPropertyName )] [ValidateNotNullOrEmpty()] [String] $ServerPath, # Location to save the selected file [Alias('FullName', 'Path')] [Parameter( Mandatory, Position = 1, ValueFromPipelineByPropertyName )] [ValidateNotNullOrEmpty()] [String] $DestinationPath, # Active TFVC Session [Parameter()] [ValidateNotNullOrEmpty()] [TFVCSession] $TFVCSession = (Get-TFVCSession) ) process { try { if ( $PSCmdlet.ShouldProcess( $DestinationPath ) ) { $TFVCSession.DownloadFile( $ServerPath, $DestinationPath ) } } catch { $PSCmdlet.ThrowTerminatingError( $PSItem ) } } } # .\TFVC\Public\Get-TFVCHistory.ps1 function Get-TFVCHistory { <# .Synopsis Get the history for a given server path .Example Get-TFVCHistory -Path $Path .Notes #> [cmdletbinding()] param( # The server path to checck the history on. Supports wildcards [Alias('Path')] [Parameter( Mandatory, Position = 0, ValueFromPipelineByPropertyName )] [ValidateNotNullOrEmpty()] [string] $ServerPath, # User to search the history for [Parameter( Position = 1, ValueFromPipelineByPropertyName )] [String] $User = [NullString]::Value, # max number of history items to return [Parameter( ValueFromPipelineByPropertyName )] [Int32] $MaxCount = [Int32]::MaxValue, # include change information [Parameter( ValueFromPipelineByPropertyName )] [Switch] $IncludeChanges, # Sort the results Ascending [Parameter( ValueFromPipelineByPropertyName )] [Switch] $SortAscending, # Active TFVC Session [Parameter()] [ValidateNotNullOrEmpty()] [TFVCSession] $TFVCSession = (Get-TFVCSession) ) process { try { $TFVCSession.GetHistory( $ServerPath, $User, $MaxCount, $IncludeChanges, $SortAscending ) } catch { $PSCmdlet.ThrowTerminatingError( $PSItem ) } } end { } } # .\TFVC\Public\Get-TFVCLatest.ps1 function Get-TFVCLatest { <# .Synopsis Gets the latest changes for all the mappings in the workspace .Example New-TFVCSession -ServerURI https://tfs -ProjectCollection DevOps $workspace = Get-TFVCWorkspace $workspace | Get-TFVCLatest .Notes #> [cmdletbinding(SupportsShouldProcess)] param( # A workspace to get latest [Parameter( Position = 0, ValueFromPipeline )] [ValidateNotNullOrEmpty()] [Workspace] $Workspace = (Get-TFVCActiveWorkspace) ) process { try { if ( $null -ne $Workspace -and $PSCmdlet.ShouldProcess( $Workspace.DisplayName ) ) { $Workspace.Get() } } catch { $PSCmdlet.ThrowTerminatingError( $PSItem ) } } } # .\TFVC\Public\Get-TFVCMergeCandidate.ps1 function Get-TFVCMergeCandidate { <# .Synopsis Compares 2 branches and get the changeset that are different between them .Example Get-TFVCMergeCandidate -SourceBranch $SourceBranch -TargetBranch $TargetBbranch -Workspace $Workspace .Notes #> [cmdletbinding()] param( # Source banch with the changes that need to be merged [Parameter( Mandatory, Position = 1, ValueFromPipelineByPropertyName )] [ValidateNotNullOrEmpty()] [String] $SourceBranch, # Target branch to merge the changes into [Parameter( Mandatory, Position = 2, ValueFromPipelineByPropertyName )] [ValidateNotNullOrEmpty()] [String] $TargetBranch, # Active TFVC Session [Parameter()] [ValidateNotNullOrEmpty()] [TFVCSession] $TFVCSession = (Get-TFVCSession) ) begin { $recursive = [RecursionType]::Full } process { try { $MergeCandidate = $TFVCSession.VersionControlServer.GetMergeCandidates( $SourceBranch, $TargetBranch, $recursive ) $MergeCandidate.ChangeSet } catch { $PSCmdlet.ThrowTerminatingError( $PSItem ) } } } # .\TFVC\Public\Get-TFVCPendingChange.ps1 function Get-TFVCPendingChange { <# .Synopsis Gets the pending changes in the workspace .Example Get-TFVCPendingChange .Notes #> [Alias('Get-TFVCPendingChanges', 'TFPending')] [cmdletbinding()] param( # The Workspace [Parameter( Position = 0, ValueFromPipeline )] [Workspace] $Workspace = (Get-TFVCActiveWorkspace) ) process { try { $Workspace.GetPendingChanges() } catch { $PSCmdlet.ThrowTerminatingError( $PSItem ) } } } # .\TFVC\Public\Get-TFVCSession.ps1 function Get-TFVCSession { <# .Synopsis Gets the current active session .Example Get-TFVCSession .Notes #> [Alias('Get-TFVCConnection', 'GTFVCS')] [cmdletbinding()] param () process { if ( $null -eq $script:MasterTFVCSession ) { Write-Warning 'There are no active TFVC sessions, please run [New-TFVCSession] to connect to a server' } else { $script:MasterTFVCSession } } } # .\TFVC\Public\Get-TFVCWorkspace.ps1 function Get-TFVCWorkspace { <# .Synopsis Gets the local workspace .Example Get-TFVCWorkspace -Path $Path .Notes #> [cmdletbinding( DefaultParameterSetName = 'Default' )] [OutputType('Microsoft.TeamFoundation.VersionControl.Client.Workspace')] param( # Workspace name [Alias('WorkspaceName', 'Workspace')] [Parameter( Position = 0, ValueFromPipelineByPropertyName, ParameterSetName = 'Default' )] [ValidateNotNullOrEmpty()] [ValidateLength(1, 64)] [String] $Name = "${env:COMPUTERNAME}-Default", # Workspace owner [Alias('WorkspaceOwner')] [Parameter( Position = 0, ValueFromPipelineByPropertyName, ParameterSetName = 'Default' )] [ValidateNotNullOrEmpty()] [String] $Owner = $env:USERNAME, # Local path to a working folder [Alias('LocalPath', 'Folder', 'Directory', 'FullName', 'WorkingFolder')] [Parameter( Mandatory, Position = 0, ValueFromPipelineByPropertyName, ParameterSetName = 'LocalPath' )] [ValidateNotNullOrEmpty()] [String] $Path, # Active TFVC Session [Parameter()] [ValidateNotNullOrEmpty()] [TFVCSession] $TFVCSession = (Get-TFVCSession), # Sets the resulting workspace as the active workspace [switch] $SetActiveWorkspace ) process { try { $workspace = $null if ( $null -eq $TFVCSession ) { Write-Warning 'No TFVCSession available to retreive workspace' return } switch ( $PSCmdlet.ParameterSetName ) { 'LocalPath' { Write-Debug "Working folder path [$Path]" $workspace = $TFVCSession.GetWorkspaceFromPath( $Path ) } default { $workspace = $TFVCSession.GetWorkspace( $PSBoundParameters.Name, $Owner ) } } if ( $SetActiveWorkspace ) { $workspace | Set-TFVCActiveWorkspace } return $workspace } catch [WorkspaceNotFoundException] { Write-Verbose 'The workspace could not be found' } catch { $PSCmdlet.ThrowTerminatingError( $PSItem ) } } } # .\TFVC\Public\Get-TFVCWorkspaceMapping.ps1 function Get-TFVCWorkspaceMapping { <# .Synopsis Gets the folder mappings in the workspace .Example New-TFVCSession -ServerURI https://tfs -ProjectCollection DevOps $workspace = Get-TFVCWorkspace $Workspace | Get-TFVCWorkspaceMapping .Notes #> [cmdletbinding()] param( # A workspace to add a source mapping to [Parameter( Mandatory, Position = 0, ValueFromPipeline )] [ValidateNotNullOrEmpty()] [Workspace] $Workspace, # The TFS locaion to map to the local system [Alias('SourcePath', 'TFSLocaion', 'ServerItem')] [Parameter( Position = 1, ValueFromPipelineByPropertyName )] [ValidateNotNullOrEmpty()] [String] $Source = '*', # The location on the local system that gets mapped [Alias('DestinationPath', 'Path', 'LocalPath', 'FullName', 'LocalItem')] [Parameter( Position = 2, ValueFromPipelineByPropertyName )] [ValidateNotNullOrEmpty()] [String] $Destination = '*' ) process { try { $Workspace.Folders | Where {$_.ServerItem -like $Source -and $_.LocalItem -like $Destination} } catch { $PSCmdlet.ThrowTerminatingError( $PSItem ) } } } # .\TFVC\Public\Merge-TFVCChangeset.ps1 function Merge-TFVCChangeset { <# .Synopsis Performs a merge in the workspace with the specified changes .Example Merge-TFVCChangeset -Path $Path .Notes Workspace.Merge: https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2013/bb139330%28v%3dvs.120%29 MergeOptionsEx: https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2013/ff736044%28v%3dvs.120%29 #> [cmdletbinding(SupportsShouldProcess)] [OutputType('[Microsoft.TeamFoundation.VersionControl.Client.GetStatus]')] param( # the workspace [Parameter( Position = 0, ValueFromPipeline, ParameterSetName = 'Workspace' )] [Workspace] $Workspace = (Get-TFVCActiveWorkspace), # Source banch with the changes that need to be merged [Parameter( Mandatory, Position = 0, ValueFromPipelineByPropertyName )] [ValidateNotNullOrEmpty()] [String] $SourceBranch, # Target branch to merge the changes into [Parameter( Mandatory, Position = 1, ValueFromPipelineByPropertyName )] [ValidateNotNullOrEmpty()] [String] $TargetBranch, # First or oldest changeset in the list to merge [Alias('Changeset', 'Start', 'First')] [Parameter( Mandatory, Position = 2, ValueFromPipelineByPropertyName )] [ValidateNotNullOrEmpty()] [Changeset] $FromChangeset, # Latest or newest change to be merged [Alias('Last', 'End')] [Parameter( Position = 3, ValueFromPipelineByPropertyName )] [Changeset] $ToChangeset, # Special options to use for the merge. Default is None [Parameter()] [MergeOptionsEx] $MergeOptions = [MergeOptionsEx]::None, # Specified lock level [Parameter()] [LockLevel] $LockLevel = [LockLevel]::None, # Recursion type [Parameter()] [RecursionType] $RecursionType = [RecursionType]::Full ) process { try { if ( $null -eq $ToChangeset ) { $ToChangeset = $FromChangeset } $fromVersion = [ChangesetVersionSpec]::new($FromChangeset.ChangesetId) $toVersion = [ChangesetVersionSpec]::new($ToChangeset.ChangesetId) # Get the results of a merge without doing a merge if ( -Not $PSCmdlet.ShouldProcess($TargetBranch) ) { $MergeOptions = $MergeOptions -bor [MergeOptionsEx]::NoMerge } $status = $Workspace.Merge( $SourceBranch, $TargetBranch, $fromVersion, $toVersion, $LockLevel, $RecursionType, $MergeOptions ) $status } catch { $PSCmdlet.ThrowTerminatingError( $PSItem ) } } } # .\TFVC\Public\New-TFVCSession.ps1 function New-TFVCSession { <# .Synopsis Creates a connection to a TFS or VSTS endpoint .Example New-TFVCSession -Path $Path .Notes #> [Alias('Open-TFVCConnection', 'NTFVCS')] [CmdletBinding()] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '')] param( # TFS or VSTS endpoint [Parameter( Mandatory, Position = 0, ValueFromPipelineByPropertyName )] [ValidateNotNullOrEmpty()] [uri] $ServerURI, # Project Collection Name [Parameter( Mandatory, Position = 1, ValueFromPipelineByPropertyName )] [ValidateNotNullOrEmpty()] [string] $ProjectCollection, # Credential [Parameter( Position = 2, ValueFromPipelineByPropertyName )] [ValidateNotNullOrEmpty()] [PSCredential] $Credential, # Pass the session object to the pipeline [switch] $PassThru ) process { try { Write-Verbose ('Connectiong to TFVC URI [{0}] and Project Collection [{1}]' -f $ServerURI, $ProjectCollection ) $script:MasterTFVCSession = $null if ( $null -ne $Credential ) { Write-Debug (' With Credential [{0}]' -f $Credential.UserName ) $script:MasterTFVCSession = [TFVCSession]::New( $ServerURI, $ProjectCollection, $Credential ) } else { Write-Debug ' With Default Credential' $script:MasterTFVCSession = [TFVCSession]::New( $ServerURI, $ProjectCollection ) } if ( $PassThru ) { return $script:MasterTFVCSession } } catch { $PSCmdlet.ThrowTerminatingError( $PSItem ) } } } # .\TFVC\Public\New-TFVCShelveset.ps1 function New-TFVCShelveset { <# .Synopsis Creates a Shelveset with the current pending changes .Example TFShelve .Example New-TFVCShelveset -Workspace $Workspace .Notes Workspace.Shelve: https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2013/bb139422(v%3dvs.120) Shelveset Class: https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2013/bb171628%28v%3dvs.120%29 #> [Alias('TFShelve')] [cmdletbinding(SupportsShouldProcess)] param( # The Workspace [Parameter( Position = 0, ValueFromPipelineByPropertyName )] [String] $Name = ('{0}-{1:yyyyMMddHHmmss}' -f $env:USERNAME, (Get-Date) ), # The message or comment on the shelveset [Parameter( Position = 1, ValueFromPipelineByPropertyName )] [String] $Comment = $env:USERNAME, # The Workspace [Parameter( Position = 2, ValueFromPipeline )] [Workspace] $Workspace = (Get-TFVCActiveWorkspace), # Pending changes to shelve [Parameter( Position = 3, ValueFromPipeline )] [PendingChange[]] $PendingChange = (Get-TFVCPendingChange), # Active TFVC Session [Parameter()] [ValidateNotNullOrEmpty()] [TFVCSession] $TFVCSession = (Get-TFVCSession), # ShelvingOptions [Parameter()] [ValidateNotNullOrEmpty()] [ShelvingOptions] $ShelvingOptions = [ShelvingOptions]::Replace ) process { try { $shelveset = $TFVCSession.CreateShelveset( $Name ) $shelveset.Comment = $Comment if ( $PSCmdlet.ShouldProcess( $Workspace.DisplayName ) ) { $Workspace.Shelve( $shelveset, $PendingChange, $ShelvingOptions ) return $shelveset } } catch { $PSCmdlet.ThrowTerminatingError( $PSItem ) } } } # .\TFVC\Public\New-TFVCWorkspace.ps1 function New-TFVCWorkspace { <# .Synopsis Creates a local workspace .Example New-TFVCWorkspace -Path $Path .Notes Name must be unique per owner #> [cmdletbinding(SupportsShouldProcess)] [OutputType('Microsoft.TeamFoundation.VersionControl.Client.Workspace')] param( # Parameter help description [Parameter( Position = 0, ValueFromPipelineByPropertyName )] [ValidateNotNullOrEmpty()] [ValidateLength(1, 64)] [String] $Name = "${env:COMPUTERNAME}-Default", # Active TFVC Session [Parameter()] [ValidateNotNullOrEmpty()] [TFVCSession] $TFVCSession = (Get-TFVCSession), # Sets this workspace as the active workspace [switch] $SetActiveWorkspace ) process { try { if ( $PSCmdlet.ShouldProcess( $Name ) ) { $workspace = $TFVCSession.CreateWorkspace( $Name ) if ( $SetActiveWorkspace ) { Set-TFVCActiveWorkspace -Workspace $workspace } return $workspace } } catch [WorkspaceExistsException] { Write-Verbose "The workspace [$Name] already exists. Using existing workspace." $TFVCWorkspace = @{ Name = $Name TFVCSession = $TFVCSession SetActiveWorkspace = [bool]$SetActiveWorkspace } Get-TFVCWorkspace @TFVCWorkspace } catch { $PSCmdlet.ThrowTerminatingError( $PSItem ) } } } # .\TFVC\Public\Remove-TFVCActiveWorkspace.ps1 function Remove-TFVCActiveWorkspace { <# .Synopsis Makes the current active workspace nolonger active. .Example Remove-TFVCActiveWorkspace .Notes #> [cmdletbinding(SupportsShouldProcess)] param() end { if ( $PSCmdlet.ShouldProcess( $script:ActiveTFVCWorkspace.DisplayName ) ) { $script:ActiveTFVCWorkspace = $null } } } # .\TFVC\Public\Remove-TFVCPendingChange.ps1 function Remove-TFVCPendingChange { <# .Synopsis Removes the specified pending changes .Example Remove-TFVCPendingChange -Path $Path .Example Remove-TFVCPendingChange | Remove-TFVCPendingChages .Notes #> [Alias('Remove-TFVCPendingChanges', 'TFUndo')] [cmdletbinding(SupportsShouldProcess)] [OutputType('[Microsoft.TeamFoundation.VersionControl.Client.PendingChange]')] param( # The Workspace [Parameter( Position = 0, ValueFromPipeline )] [Workspace] $Workspace = (Get-TFVCActiveWorkspace), # Local path to the pending change that should be removed [Alias('FullName', 'LocalItem')] [Parameter( Position = 1, ValueFromPipelineByPropertyName )] $Path, # Pending changes to commit [Parameter( Position = 2, ValueFromPipeline )] [PendingChange[]] $PendingChange = (Get-TFVCPendingChange) ) process { try { if ( $null -ne $Path ) { $PendingChange | Where LocalItem -in $Path } if ( $null -ne $PendingChange ) { if ( $PSCmdlet.ShouldProcess( ( $PendingChange.LocalItem -join ',' ) ) ) { $count = $Workspace.Undo( $PendingChange ) [PSCustomOBject]@{ LocalItem = $PendingChange.localItem UndoneChanges = $count } } } } catch { $PSCmdlet.ThrowTerminatingError( $PSItem ) } } } # .\TFVC\Public\Remove-TFVCSession.ps1 function Remove-TFVCSession { <# .Synopsis Removes the current session .Example Remove-TFVCSession -TFVCSession $TFVCSession .Notes #> [Alias('Remove-TFVCConnection', 'RTFVCS')] [cmdletbinding()] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '')] param () process { try { if ( $null -ne $script:MasterTFVCSession ) { $script:MasterTFVCSession.Disconnect() $script:MasterTFVCSession = $null } } catch { $PSCmdlet.ThrowTerminatingError( $PSItem ) } } } # .\TFVC\Public\Remove-TFVCWorkspace.ps1 function Remove-TFVCWorkspace { <# .Synopsis This will delete an existing workspace. .Example Remove-TFVCWorkspace -Path $Path .Notes This implementation only deletes from the local system, but could be enhanced to delete any workspace from TFS #> [cmdletbinding(DefaultParameterSetName = 'Named', SupportsShouldProcess)] param( # Name of the workspace [Parameter( Position = 0, ValueFromPipelineByPropertyName, ParameterSetName = 'Named' )] [ValidateNotNullOrEmpty()] [ValidateLength(1, 64)] [String] $Name = "${env:COMPUTERNAME}-Default", # the workspace [Parameter( Mandatory, Position = 0, ValueFromPipeline, ParameterSetName = 'Workspace' )] [Workspace] $Workspace, # Active TFVC Session [Parameter()] [ValidateNotNullOrEmpty()] [TFVCSession] $TFVCSession = (Get-TFVCSession) ) process { try { if ( $null -eq $Workspace ) { $Workspace = Get-TFVCWorkspace -Name $Name -TFVCSession $TFVCSession } if ( $null -ne $Workspace -and $PSCmdlet.ShouldProcess( $Workspace.DisplayName ) ) { if ( $Workspace.Delete() ) { Write-Verbose "The Workspace [$($Workspace.DisplayName)] was deteled" } else { Write-Warning 'Calling delete on this workspace object returned [$false] unexpectidly. Are the red ones stuff you wanted removed? Ooh, that''s clever, Morty, but I don''t use color to sort things' } } } catch [WorkspaceDeletedException] { Write-Verbose 'This workspace has alraedy been deleted' } catch { $PSCmdlet.ThrowTerminatingError( $PSItem ) } } } # .\TFVC\Public\Remove-TFVCWorkspaceMapping.ps1 function Remove-TFVCWorkspaceMapping { <# .Synopsis Adds a source to folder mapping to the workspace .Example New-TFVCSession -ServerURI https://tfs -ProjectCollection DevOps $workspace = Get-TFVCWorkspace $workspace | Remove-TFVCWorkspaceMapping -Source '$/DevOpsTFVCTest/master' .Notes #> [cmdletbinding(DefaultParameterSetName = 'Source', SupportsShouldProcess)] param( # A workspace to add a source mapping to [Parameter( Mandatory, Position = 0, ValueFromPipeline )] [ValidateNotNullOrEmpty()] [Workspace] $Workspace, # The TFS locaion to map to the local system [Alias('SourcePath', 'TFSLocaion', 'ServerItem')] [Parameter( Mandatory, Position = 1, ValueFromPipelineByPropertyName, ParameterSetName = 'Source' )] [ValidateNotNullOrEmpty()] [String] $Source, # The location on the local system that gets mapped [Alias('DestinationPath', 'Path', 'LocalPath', 'FullName', 'LocalItem')] [Parameter( Mandatory, Position = 1, ValueFromPipelineByPropertyName, ParameterSetName = 'Destination' )] [ValidateNotNullOrEmpty()] [String] $Destination, # The location on the local system that gets mapped [Alias('WorkingFolder')] [Parameter( Mandatory, Position = 1, ValueFromPipeline, ParameterSetName = 'WorkingFolder' )] [WorkingFolder[]] $Mapping ) process { try { switch ( $PSCmdlet.ParameterSetName ) { 'Source' { $Mapping = $Workspace.Folders | Where ServerItem -eq $Source } 'Destination' { $Mapping = $Workspace.Folders | Where LocalItem -eq $Destination } } if ( $null -ne $Mapping ) { if ( $PSCmdlet.ShouldProcess( $mapping.ServerItem ) ) { foreach ($folder in $Mapping) { $Workspace.DeleteMapping( $folder ) } } } } catch [ItemNotMappedException] { Write-Verbose 'This mapping does not exist in this workspace' } catch { $PSCmdlet.ThrowTerminatingError( $PSItem ) } } } # .\TFVC\Public\Save-TFVCPendingChange.ps1 function Save-TFVCPendingChange { <# .Synopsis Commit or checking the pending changes in the workspace .Example Save-TFVCPendingChange .Notes #> [Alias('Save-TFVCPendingChanges', 'TFCommit', 'TFCheckIn')] [cmdletbinding(SupportsShouldProcess)] param( # Commit Message [Alias('Message', 'CM')] [Parameter( Mandatory, Position = 0, ValueFromPipelineByPropertyName )] [ValidateNotNullOrEmpty()] [string] $CommitMessage, # The Workspace [Parameter( Position = 2, ValueFromPipeline )] [Workspace] $Workspace = (Get-TFVCActiveWorkspace), # Filter local changes to path [Alias('FullName', 'LocalItem')] [Parameter( Position = 1, ValueFromPipelineByPropertyName )] [string[]] $Path, # Pending changes to commit [Parameter( Position = 3, ValueFromPipeline )] [PendingChange[]] $PendingChange = (Get-TFVCPendingChange) ) process { try { if ( $null -ne $Path ) { $PendingChange | Where LocalItem -in $Path } if ( $null -ne $PendingChange ) { if ( $PSCmdlet.ShouldProcess( ( $PendingChange.LocalItem -join ',' ) ) ) { $newchangeset = $Workspace.Checkin( $PendingChange, $CommitMessage ) [PSCustomObject]@{ Changeset = $newchangeset } } } else { Write-Warning "There were no pending changes to commit in workspace [$($Workspace.Displayname)]" } } catch { $PSCmdlet.ThrowTerminatingError( $PSItem ) } } } # .\TFVC\Public\Set-TFVCActiveWorkspace.ps1 function Set-TFVCActiveWorkspace { <# .Synopsis Sets a workspace as the default one for the current powershell session .Example New-TFVCSession -ServerURI https://tfs -ProjectCollection DevOps $workspace = New-TFVCWorkspace Set-TFVCActiveWorkspace -Workspace $Workspace .Example New-TFVCSession -ServerURI https://tfs -ProjectCollection DevOps New-TFVCWorkspace -SetActiveWorkspace .Notes #> [cmdletbinding(SupportsShouldProcess)] param( # The workspace [Parameter( Mandatory, Position = 0, ValueFromPipeline )] [ValidateNotNullOrEmpty()] [Workspace] $Workspace ) end { try { if ( $PSCmdlet.ShouldProcess( $Workspace.DisplayName ) ) { $script:ActiveTFVCWorkspace = $Workspace } } catch { $PSCmdlet.ThrowTerminatingError( $PSItem ) } } } |