Created
April 26, 2021 20:06
-
-
Save Ryanman/4cf6cd7b540e96a02b32011bfd1027c3 to your computer and use it in GitHub Desktop.
Clones all the repositories in an Azure DevOps collection in a well-organized folder structure
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#Ensure you create a PAT, following the instructions here: https://dev.to/omiossec/getting-started-with-azure-devops-api-with-powershell-59nn | |
#Additional Credit: https://blog.rsuter.com/script-to-clone-all-git-repositories-from-your-vsts-collection/ | |
#I suggeste executing from C:/Projects. This script will create a folder for each Team Project/Client with repos within each. | |
#Finally note that git clone operations count as "Errors" in powershell, and appear red. It's more work than is worth it to change it. | |
param( | |
[string] $email = $(Throw "--Email is required."), #required parameter | |
[string] $pat = $(Throw "--PAT is Required"), #required parameter | |
[string] $url = $(Throw "--Collection URL is required.") #required parameter pointing to the default collection, URL is generally https://{tenant}.visualstudio.com/defaultcollection | |
) | |
$originalDirectory = Get-Location | |
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $email,$pat))) | |
$headers = @{ | |
"Authorization" = ("Basic {0}" -f $base64AuthInfo) | |
"Accept" = "application/json" | |
} | |
Add-Type -AssemblyName System.Web | |
$gitcred = ("{0}:{1}" -f [System.Web.HttpUtility]::UrlEncode($username),$password) | |
#You can use this code instead if you wish to build a "Flat" folder with repositories. Move the inner loop per-project to here. | |
#Write-Host "Retrieving Repositories...`n" | |
#$reposResponse = Invoke-WebRequest -Headers $headers -Uri ("{0}/_apis/git/repositories?api-version=1.0" -f $url) | |
#$repos = convertFrom-JSON $resp.Content | |
Write-Host "Getting Projects..." | |
$projectsUrl = "$collection/_apis/projects?api-version=4.0" | |
$projectResponse = Invoke-Webrequest -Headers $headers -Uri ("{0}/_apis/projects?api-version=4.0" -f $url) | |
$projects = ConvertFrom-Json $projectResponse | |
$projects.value.ForEach({ | |
$folderToCreate = Join-Path -Path $originalDirectory -ChildPath $_.name | |
if (!(Test-Path $folderToCreate -PathType Container)) { | |
Write-Host "Creating folder for Project $($_.name)" | |
New-Item -ItemType Directory -Force -Path $folderToCreate | |
} else { | |
Write-Host "Skipping folder creation for project $($_.name), as it already exists" | |
} | |
Set-Location $folderToCreate | |
$reposUrl = "$url/$($_.name)/_apis/git/repositories?api-version=4.0" | |
$reposResponse = Invoke-Webrequest -Headers $headers -Uri $reposUrl | |
$repos = ConvertFrom-Json $reposResponse | |
$repos.value.ForEach({ | |
$name = $_.name | |
Write-Host "Cloning $name Repos" | |
try { | |
$credUrl = $_.remoteUrl -replace "://", ("://{0}@" -f $gitcred) | |
git clone $credUrl --branch master --single-branch | |
#git clone $_.remoteUrl --branch master --single-branch #this will automatically create/use GitForWindows token after a login prompt if you have issues with the upper 2 lines | |
} | |
catch { | |
Write-Host $PSItem.Exception.Message -ForegroundColor RED | |
Write-Host "Error at URL $_.remoteUrl" | |
Set-Location $originalDirectory | |
} | |
}) | |
Write-Host "Cleaning URL Space encoding for repo folders..." | |
Get-ChildItem $folderToCreate | | |
Where {$_.Name -Match '%20'} | | |
Rename-Item -NewName {$_.name -replace '%20',' ' } #Rename-Item { $_.Name -replace "%20"," " } | |
Set-Location $originalDirectory | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment