简体   繁体   中英

How to download only updated files from TFS in local directory using Powershell

I need to download selected folders from a TFS Source control to local file folders. I am able to perform that using following script:

Add-PSSnapin Microsoft.TeamFoundation.PowerShell
$securePass = ConvertTo-SecureString -AsPlainText -Force -String "mypassword"
$uri = "serverURL"
$cred =  New-Object System.Management.Automation.PSCredential("myusername",$securePass)

$tfsServer = Get-TfsServer -Name $uri -Credential $cred
$structureService = $tfsServer.GetService("Microsoft.TeamFoundation.Server.ICommonStructureService")

$versionControlService = $tfsServer.GetService("Microsoft.TeamFoundation.VersionControl.Client.VersionControlServer")

$pathsToDownload=[System.Collections.ArrayList]@()
$pathsToDownload.add("$/myfirstPath")
$pathsToDownload.add("$/mysecondPath")
$pathsToDownload.add("$/mythirdPath")

$localTFSRoot = "c:\tfs"
$serverRoot = "$/"
foreach ($serverPath in $pathsToDownload) {
  write-host "Working with $serverPath"
  $items = Get-TfsChildItem -Server $tfsServer -Item $serverPath -Recurse
  foreach ($item in $items) {
    $destinationPath=$($Item.ServerItem.Replace($serverRoot,$localTFSRoot)).replace("\","/")
    write-host "Downloading $destinationPath"
    if ($item.ItemType -eq "Folder") {
       #create directory if it doesn't already exist
       if (-Not (Test-Path $destinationPath -PathType Container -IsValid)) {
          New-Item -ItemType Directory -Path $destinationPath -Force
       }
    } else {
       $versionControlService.DownloadFile($item.ServerItem,$destinationPath)
    }
  }
}

However, this script downloads all the files every time. I would like to download the files only if there is change in the file. Is there a way to perform such operation through powershell operations? I am not sure what does getItem do versus downloadfile.

Thank you for your help.

UPDATE *** I was able to download using the workspace route but I haven't tried if it works only for update. However, the workspace.get() is downloading without any verbose output. Is there a way to get it to list the files it is working with so that user doesn't think it is hanged while it is downloading?

if ( (Get-PSSnapin -Name Microsoft.TeamFoundation.PowerShell -ErrorAction SilentlyContinue) -eq $null ) {
 Add-PSSnapin Microsoft.TeamFoundation.PowerShell
}
$securePass = ConvertTo-SecureString -AsPlainText -Force -String "mypassword"
$uri = "https://myserver"
$cred =  New-Object System.Management.Automation.PSCredential("myusername",$securePass)

$tfsServer = Get-TfsServer -Name $uri -Credential $cred
$structureService = $tfsServer.GetService("Microsoft.TeamFoundation.Server.ICommonStructureService")
$versionControlService = $tfsServer.GetService("Microsoft.TeamFoundation.VersionControl.Client.VersionControlServer")

$workSpaceName = $env:USERNAME + "-IMAG"

$localTFSWorkspace="c:\tfswspace"
$serverRoot = "$/myproject"
$pathsToDownload=[System.Collections.ArrayList]@()
$pathsToDownload.add("$/myproject/path1")
$pathsToDownload.add("$/myproject/path2")

$testPath = $($pathsToDownload[0].Replace($serverRoot,$localTFSWorkspace)).replace("/","\")

if (!(Test-Path $localTFSWorkspace -PathType Container)) {
  New-Item $localTFSWorkspace -ItemType Directory -Force
}

# Check if workspace already exists
     $workspace = $versionControlService.TryGetWorkspace($testPath)
     if ($workspace -eq $null) {
       #Workspace doesn't exist, we need to create one
       $workspace = $versionControlService.CreateWorkspace($workSpaceName,$cred.UserName, 'Workspace for Repository Sync')
     }

 #create mappings if these don't exist 
 foreach ($serverPath in $pathsToDownload) {
      $localPath = $($serverPath.Replace($serverRoot,$localTFSWorkspace)).replace("/","\")
      if (!(Test-Path $localPath -PathType Container)) {
         New-Item $localPath -ItemType Directory -Force
      }

    $workingFolder =  $workspace.TryGetWorkingFolderForServerItem($serverPath)

    if ($workingFolder -eq $null) {
      #create mapping here
      $workspace.Map($serverPath,$localPath)
    }
 }
 # Now mappings are done -- get items now
 $workspace.get()

You need to create a workspace to to get all files. When you perform Get , you'll see all files are downloaded in the workspace. If the files in the workspace are latest, no file will be downloaded. Once there are new updated files in TFS, after performing Get , only updated files will be replaced. Here is a C# code snippet about how to create a workspacce:

            TfsTeamProjectCollection tfs = new TfsTeamProjectCollection(new Uri("http://tfs:8080/tfs/defaultCollection"));
            var versioncontrols = tfs.GetService<VersionControlServer>();

            var workspace = versioncontrols.CreateWorkspace("workspacename", "workspaceowner");

            String ServerFolder = @"$/xxxx/xxxx";
            String LocalFolder = @"E:\test";

            WorkingFolder workfolder = new WorkingFolder(ServerFolder, LocalFolder);
            workspace.CreateMapping(workfolder);

            workspace.Get();

I was able to get the code using workspace option using the code sample below.

if ( (Get-PSSnapin -Name Microsoft.TeamFoundation.PowerShell -ErrorAction SilentlyContinue) -eq $null ) {
     Add-PSSnapin Microsoft.TeamFoundation.PowerShell
    }
    $securePass = ConvertTo-SecureString -AsPlainText -Force -String "mypassword"
    $uri = "https://myserver"
    $cred =  New-Object System.Management.Automation.PSCredential("myusername",$securePass)

$tfsServer = Get-TfsServer -Name $uri -Credential $cred
$structureService = $tfsServer.GetService("Microsoft.TeamFoundation.Server.ICommonStructureService")
$versionControlService = $tfsServer.GetService("Microsoft.TeamFoundation.VersionControl.Client.VersionControlServer")

$workSpaceName = $env:USERNAME + "-IMAG"

$localTFSWorkspace="c:\tfswspace"
$serverRoot = "$/myproject"
$pathsToDownload=[System.Collections.ArrayList]@()
$pathsToDownload.add("$/myproject/path1")
$pathsToDownload.add("$/myproject/path2")

$testPath = $($pathsToDownload[0].Replace($serverRoot,$localTFSWorkspace)).replace("/","\")

if (!(Test-Path $localTFSWorkspace -PathType Container)) {
  New-Item $localTFSWorkspace -ItemType Directory -Force
}

# Check if workspace already exists
     $workspace = $versionControlService.TryGetWorkspace($testPath)
     if ($workspace -eq $null) {
       #Workspace doesn't exist, we need to create one
       $workspace = $versionControlService.CreateWorkspace($workSpaceName,$cred.UserName, 'Workspace for Repository Sync')
     }

 #create mappings if these don't exist 
 foreach ($serverPath in $pathsToDownload) {
      $localPath = $($serverPath.Replace($serverRoot,$localTFSWorkspace)).replace("/","\")
      if (!(Test-Path $localPath -PathType Container)) {
         New-Item $localPath -ItemType Directory -Force
      }

    $workingFolder =  $workspace.TryGetWorkingFolderForServerItem($serverPath)

    if ($workingFolder -eq $null) {
      #create mapping here
      $workspace.Map($serverPath,$localPath)
    }
 }
 # Now mappings are done -- get items now
 $workspace.get()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM