<# .SYNOPSIS Exports Azure DevOps pull request information across all repositories to a CSV file. .DESCRIPTION This script retrieves all repositories from an Azure DevOps project and then collects detailed information about all pull requests (active, completed, and abandoned) from each repository. The information is exported to a timestamped CSV file for analysis and reporting. .PARAMETER Organization The Azure DevOps organization name. Defaults to "effectory" if not specified. .PARAMETER Project The Azure DevOps project name. Defaults to "survey software" if not specified. .EXAMPLE .\PullRequests.ps1 Exports pull request information using the default organization and project settings. .EXAMPLE .\PullRequests.ps1 -Organization "myorg" -Project "myproject" Exports pull request information for a specific organization and project. .OUTPUTS Creates a timestamped CSV file in the current directory with the format: "yyyy-MM-dd HHmm pull requests.csv" The CSV contains the following columns: - RepositoryId: Repository unique identifier - RepositoryName: Repository name - DefaultBranch: Repository default branch - RepositoryWebUrl: Repository web URL - PullRequestId: Pull request unique identifier - PullRequestDate: Pull request creation date - PullRequestName: Pull request title - PullRequestCreatedBy: Pull request author - PullRequestReviewers: Comma-separated list of reviewers - PullRequestStatus: Pull request status (Active, Completed, Abandoned) - PullRequestWebUrl: Direct URL to the pull request - CompletionBypassReason: Reason for bypassing completion requirements (if any) .NOTES Author: Cloud Engineering Team Created: 2025 Requires: PowerShell 5.1 or later, Azure CLI installed and authenticated Dependencies: Azure CLI (az) must be installed and user must be authenticated Prerequisites: - Install Azure CLI: https://docs.microsoft.com/en-us/cli/azure/install-azure-cli - Authenticate: az login - Set default subscription if needed: az account set --subscription "subscription-name" The script processes all active repositories in the specified project and retrieves all pull requests regardless of their status (active, completed, abandoned). .LINK https://docs.microsoft.com/en-us/cli/azure/repos/pr #> param( [Parameter(Mandatory = $false, HelpMessage = "Azure DevOps organization name")] [string]$Organization = "effectory", [Parameter(Mandatory = $false, HelpMessage = "Azure DevOps project name")] [string]$Project = "survey software" ) # Define a class to structure pull request information class PullRequest { [string] $RepositoryId = "" # Repository unique identifier [string] $RepositoryName = "" # Repository display name [string] $DefaultBranch = "" # Repository default branch (e.g., main, master) [string] $RepositoryWebUrl = "" # Repository web URL in Azure DevOps [string] $PullRequestId = "" # Pull request unique identifier [string] $PullRequestDate = "" # Pull request creation timestamp [string] $PullRequestName = "" # Pull request title/name [string] $PullRequestCreatedBy = "" # Pull request author display name [string] $PullRequestReviewers = "" # Comma-separated list of reviewer names [string] $PullRequestStatus = "" # PR status: Active, Completed, Abandoned [string] $PullRequestWebUrl = "" # Direct URL to view the pull request [string] $CompletionBypassReason = "" # Reason for bypassing completion policies } # Generate timestamped filename for the output CSV [string] $date = Get-Date -Format "yyyy-MM-dd HHmm" $fileName = ".\$date pull requests.csv" # Display script execution banner Write-Host "========================================================================================================================================================================" Write-Host "Creating pull request overview for Organization: $Organization, Project: $Project" Write-Host "Output file: $fileName" Write-Host "Note: This script requires Azure CLI to be installed and authenticated (az login)" Write-Host "========================================================================================================================================================================" # Retrieve all active repositories from the Azure DevOps project Write-Host "Fetching repositories from project '$Project'..." -ForegroundColor Yellow $repos = az repos list --organization "https://dev.azure.com/$Organization/" --project "$Project" | ConvertFrom-Json | Select-Object | Where-Object { $true -ne $_.isDisabled } Write-Host "Found $($repos.Count) active repositories" -ForegroundColor Green # Process each repository to collect pull request information $totalPullRequests = 0 foreach ($repo in $repos) { Write-Host "Processing repository: $($repo.name)" -ForegroundColor Cyan # Retrieve all pull requests from the current repository (all statuses: active, completed, abandoned) $prs = az repos pr list --project "$Project" --repository "$($repo.name)" --organization "https://dev.azure.com/$Organization/" --status all | ConvertFrom-Json | Select-Object Write-Host " Found $($prs.Count) pull requests" -ForegroundColor Gray # Initialize array to store pull request information for this repository [PullRequest[]]$Result = @() # Process each pull request in the current repository foreach ($pr in $prs) { # Create new pull request object and populate all properties [PullRequest] $pullRequest = [PullRequest]::new() $pullRequest.RepositoryId = $repo.id $pullRequest.RepositoryName = $repo.name $pullRequest.DefaultBranch = $repo.defaultBranch $pullRequest.RepositoryWebUrl = $repo.webUrl $pullRequest.PullRequestId = $pr.pullRequestId $pullRequest.PullRequestDate = $pr.creationDate $pullRequest.PullRequestName = $pr.title $pullRequest.PullRequestCreatedBy = $pr.createdBy.displayName # Join all reviewer names into a comma-separated string $pullRequest.PullRequestReviewers = $pr.reviewers | join-string -property displayName -Separator ',' $pullRequest.PullRequestStatus = $pr.status # Construct direct URL to the pull request $pullRequest.PullRequestWebUrl = "$($repo.webUrl)/pullrequest/$($pr.pullRequestId)" # Capture bypass reason if completion policies were bypassed $pullRequest.CompletionBypassReason = $pr.completionOptions.bypassReason # Add to results array $Result += $pullRequest } # Append results for this repository to the CSV file $Result | Export-Csv -Path $fileName -Append -NoTypeInformation $totalPullRequests += $Result.Count } # Display completion summary Write-Host "========================================================================================================================================================================" Write-Host "Export completed successfully!" -ForegroundColor Green Write-Host "Total repositories processed: $($repos.Count)" -ForegroundColor Yellow Write-Host "Total pull requests exported: $totalPullRequests" -ForegroundColor Yellow Write-Host "Output file: $fileName" -ForegroundColor Yellow Write-Host "========================================================================================================================================================================"