Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions PowerShell/Snippets/CloneUpdate-Repos.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Define the list of Azure DevOps project names
$organization = "yourOrg"
$destinationFolder = "/Users/user/$organization"
$pat = ""
$VerbosePreference = 'Continue'

# Function to get all projects in the organization
function Get-AdoProjects {
$uri = "https://dev.azure.com/$organization/_apis/projects?api-version=6.0"
$response = Invoke-RestMethod -Uri $uri -Headers @{Authorization = "Basic " + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$pat")) }
return $response.value
}

# Function to get repositories for a given project
function Get-AdoRepositories($project) {
$uri = "https://dev.azure.com/$organization/$project/_apis/git/repositories?api-version=6.0"
$uri = $uri -replace " ", "%20"
Write-Verbose $uri
$response = Invoke-RestMethod -Uri $uri -Headers @{Authorization = "Basic " + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$pat")) }
return $response.value
}

# Function to clone or update repositories
function CloneOrUpdateRepo($repo, $projectFolder) {
$repoName = $repo.name
$repoUrl = $repo.remoteUrl
$repoFolder = "$projectFolder/$repoName"

if (-not (Test-Path -Path $repoFolder)) {
Write-Verbose "Cloning $($repo.name)"
git clone $repoUrl $repoFolder
} else {
Write-Verbose "Pulling/Refreshing $($repo.name)"
Set-Location -Path $repoFolder
git checkout main
git pull
Set-Location -Path $projectFolder
}
}

# Main script
Write-Verbose "Getting projects ..."
$projects = Get-AdoProjects
Write-Verbose "Found $($projects.Count) projects: $($projects.name)"
foreach ($project in $projects) {
$projectFolder = "$destinationFolder/$($project.name)"
if (-not (Test-Path -Path $projectFolder)) {
Write-Verbose "Creating folder $projectFolder"
New-Item -ItemType Directory -Path $projectFolder
}

Write-Verbose "Getting repos for $($project.name) ..."
$repos = Get-AdoRepositories -project $project.name
Write-Verbose "Found $($repos.Count) repos: $($repos.name)"
# ask to proceed
Read-Host "Press Enter to continue"
foreach ($repo in $repos) {
$response = Read-Host "Do you want to clone/update the repo $($repo.name)? (y/n)"
if ($response -eq 'y') {
CloneOrUpdateRepo -repo $repo -projectFolder $projectFolder
} else {
Write-Verbose "Skipping $($repo.name)"
}
}
}
115 changes: 115 additions & 0 deletions PowerShell/Snippets/Create-BuildValidationPolicies.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
# Define the list of Azure DevOps project names
$organization = "org1"
$pat = "<pat>"
$projects = @(
[PSCustomObject]@{
name = "project1"
}
)
$VerbosePreference = 'Continue'

# Log in to Azure DevOps using PAT
$env:AZURE_DEVOPS_EXT_PAT = "$pat"

# Function to get all projects in the organization
function Get-AdoProjects {
$uri = "https://dev.azure.com/$organization/_apis/projects?api-version=6.0"
$response = Invoke-RestMethod -Uri $uri -Headers @{Authorization = "Basic " + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$pat")) }
return $response.value
}

# Function to get repositories for a given project
function Get-AdoRepositories($project) {
$uri = "https://dev.azure.com/$organization/$project/_apis/git/repositories?api-version=6.0"
$uri = $uri -replace " ", "%20"
$response = Invoke-RestMethod -Uri $uri -Headers @{Authorization = "Basic " + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$pat")) }
return $response.value
}

# Function to get all Azure Pipelines
function Get-AdoPipelines($project) {
$uri = "https://dev.azure.com/$organization/$project/_apis/pipelines?api-version=6.0"
$uri = $uri -replace " ", "%20"
$response = Invoke-RestMethod -Uri $uri -Headers @{Authorization = "Basic " + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$pat")) }
return $response.value
}

# Function to get all build policies
function Get-AdoBuildPolicies($project) {
$uri = "https://dev.azure.com/$organization/$project/_apis/policy/configurations?api-version=6.0"
$uri = $uri -replace " ", "%20"
$response = Invoke-RestMethod -Uri $uri -Headers @{Authorization = "Basic " + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$pat")) }
return $response.value
}

function CreateBuildValidationPolicy($project, $repo, $buildDefinition) {
# check matching policies
$matchingPolicies = $buildPolicies | Where-Object { $_.settings.buildDefinitionId -eq $buildDefinition.id }
if ($matchingPolicies) {
Write-Verbose "Policy already exists for $($repo.name) using pipeline $($buildDefinition.name). Updating."
az repos policy build update `
--id $matchingPolicies.id `
--blocking $false `
--branch main `
--build-definition-id $buildDefinition.id `
--display-name $repo.name `
--enabled $true `
--manual-queue-only $false `
--queue-on-source-update-only $false `
--repository-id $repo.id `
--valid-duration 0 `
--project $project.name

# Build Validation Policy
# --blocking $false - Policy Requirement: Optional
# --manual-queue-only $false - Trigger: Manual
# --valid-duration 0 - Build expiration: Immediately when main is updated
} else {
Write-Verbose "Creating build validation policy for $($repo.name) using pipeline $($buildDefinition.name)."
az repos policy build create `
--blocking $false `
--branch main `
--build-definition-id $buildDefinition.id `
--display-name $repo.name `
--enabled $true `
--manual-queue-only $false `
--queue-on-source-update-only $false `
--repository-id $repo.id `
--valid-duration 0 `
--project $project.name
}
}

# Main script
Write-Verbose "Getting projects ..."
if ($projects.Count -eq 0) {
Write-Verbose "Getting all projects ..."
$projects = Get-AdoProjects
} else {
Write-Verbose "Using provided project(s): $($projects.name)"
}
Write-Verbose "Found $($projects.Count) project(s): $($projects.name)"
foreach ($project in $projects) {
Write-Verbose "Getting repos for $($project.name) ..."
$repos = Get-AdoRepositories -project $project.name
Write-Verbose "Found $($repos.Count) repos."
$pipelines = Get-AdoPipelines -project $project.name
Write-Verbose "Found $($pipelines.Count) pipelines."
$buildPolicies = Get-AdoBuildPolicies -project $project.name
Write-Verbose "Found $($buildPolicies.Count) build policies."
# Check matching pipelines
$checkedRepos = $repos | Where-Object { $_.name -in $pipelines.name }
Write-Verbose "Found $($checkedRepos.Count) repos with matching pipelines."

Read-Host "Press Enter to continue"

foreach ($repo in $repos) {
$buildDefinition = $pipelines | Where-Object { $_.name -eq "$($repo.name)" }
# $response = Read-Host "Do you want to create build validation for repo $($repo.name) using pipeline $($buildDefinition.name)? (y/n)"
# if ($response -eq 'y') {
CreateBuildValidationPolicy -repo $repo -project $project -buildDefinition $buildDefinition
# } else {
# Write-Verbose "Skipping $($repo.name)"
# }
}
}