<# .SYNOPSIS Exports Azure DevOps pipeline information to a CSV file. .DESCRIPTION This script retrieves all build pipelines from an Azure DevOps project and exports detailed information about each pipeline to a CSV file. It collects pipeline metadata including ID, name, path, type, author, creation date, pipeline type (Classic or YAML), and edit URLs. .PARAMETER Token The Azure DevOps Personal Access Token (PAT) used for authentication. This token must have 'Build (Read)' permissions to access pipeline information. .PARAMETER Organization The Azure DevOps organization name. Defaults to "effectory" if not specified. .PARAMETER Project The Azure DevOps project name. Defaults to "Survey%20Software" if not specified. Note: URL-encoded project names should be used (spaces as %20). .EXAMPLE .\Pipelines.ps1 -Token "your-personal-access-token" Exports pipeline information using the default organization and project settings. .EXAMPLE .\Pipelines.ps1 -Token "your-pat-token" -Organization "myorg" -Project "MyProject" Exports pipeline information for a specific organization and project. .EXAMPLE .\Pipelines.ps1 -Token "your-pat-token" -Project "My%20Custom%20Project" Exports pipeline information for a custom project (with URL-encoded name) using the default organization. .OUTPUTS Creates a timestamped CSV file in the current directory with the format: "yyyy-MM-dd HHmm pipelines.csv" The CSV contains the following columns: - Id: Pipeline ID - Name: Pipeline name - Path: Pipeline folder path - Type: Pipeline type (build/release) - Author: Pipeline author - CreatedDate: Pipeline creation date - PipelineType: Classic or YAML - PipelineEditUrl: Direct URL to edit the pipeline .NOTES Author: Cloud Engineering Team Created: 2025 Requires: PowerShell 5.1 or later Dependencies: Internet connectivity to Azure DevOps The script uses Azure DevOps REST API version 7.1-preview.7 to retrieve pipeline information. Ensure your Personal Access Token has the necessary permissions before running the script. .LINK https://docs.microsoft.com/en-us/rest/api/azure/devops/build/definitions/list #> param( [Parameter(Mandatory = $true, HelpMessage = "Azure DevOps Personal Access Token with Build (Read) permissions")] [string]$Token, [Parameter(Mandatory = $false, HelpMessage = "Azure DevOps organization name")] [string]$Organization = "effectory", [Parameter(Mandatory = $false, HelpMessage = "Azure DevOps project name (URL-encoded if contains spaces)")] [string]$Project = "Survey%20Software" ) # Define a class to structure pipeline information class PipelineInfo { [string] $Id = "" # Pipeline unique identifier [string] $Name = "" # Pipeline display name [string] $Path = "" # Pipeline folder path in Azure DevOps [string] $Type = "" # Pipeline type (build/release) [string] $Author = "" # Pipeline creator [string] $CreatedDate = "" # Pipeline creation timestamp [string] $PipelineType = "" # Classic or YAML pipeline type [string] $PipelineEditUrl = "" # Direct URL to edit the pipeline } # Encode the Personal Access Token for Basic Authentication # Azure DevOps requires the token to be base64 encoded with a colon prefix $encodedToken = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($Token)")) # Create authentication header for REST API calls $head = @{ Authorization =" Basic $encodedToken" } <# .SYNOPSIS Determines if a pipeline is Classic or YAML based. .DESCRIPTION Makes an additional API call to determine the pipeline process type. Returns 1 for Classic pipelines, 2 for YAML pipelines. .PARAMETER pipeLineId The unique identifier of the pipeline to check. .OUTPUTS Integer value: 1 = Classic pipeline, 2 = YAML pipeline #> function GetPipelineType { param ( [int] $pipeLineId ) # Call Azure DevOps internal API to get pipeline process type $url = "https://dev.azure.com/$Organization/$Project/_apps/hub/ms.vss-build-web.ci-designer-hub?pipelineId=$pipeLineId&__rt=fps&__ver=2" $response = Invoke-RestMethod -Uri $url -Method GET -Headers $head # Extract the definition process type from the response return $response.fps.dataProviders.data."ms.vss-build-web.pipeline-detail-data-provider".definitionProcessType } # Generate timestamped filename for the output CSV [string] $date = Get-Date -Format "yyyy-MM-dd HHmm" $fileName = ".\$date pipelines.csv" # Display script execution banner Write-Host "========================================================================================================================================================================" Write-Host "Creating pipeline overview for Organization: $Organization, Project: $Project" Write-Host "Output file: $fileName" Write-Host "========================================================================================================================================================================" # Call Azure DevOps REST API to get all build definitions $url="https://dev.azure.com/$Organization/$Project/_apis/build/definitions?api-version=7.1-preview.7" $response = Invoke-RestMethod -Uri $url -Method GET -Headers $head # Initialize array to store pipeline information [PipelineInfo[]]$Result = @() # Process each pipeline returned from the API $response.value | ForEach-Object { Write-Host "Processing pipeline: $($_.name)" -ForegroundColor Green # Determine if this is a Classic or YAML pipeline $definitionProcessType = GetPipelineType -pipeLineId $_.id # Create new pipeline info object and populate properties [PipelineInfo] $pipelineInfo = [PipelineInfo]::new() $pipelineInfo.Id = $_.id $pipelineInfo.Name = $_.name $pipelineInfo.Path = $_.path $pipelineInfo.Type = $_.type $pipelineInfo.Author = $_.authoredby.DisplayName $pipelineInfo.CreatedDate = $_.createdDate $pipelineInfo.PipelineType = $definitionProcessType -eq 1 ? "Classic" : "Yaml" # Generate appropriate edit URL based on pipeline type $pipelineInfo.PipelineEditUrl = $definitionProcessType -eq 1 ? "https://dev.azure.com/$Organization/$Project/_apps/hub/ms.vss-ciworkflow.build-ci-hub?_a=edit-build-definition&id=$($_.id)" : "https://dev.azure.com/$Organization/$Project/_apps/hub/ms.vss-build-web.ci-designer-hub?pipelineId=$($_.id)&branch=master" # Add to results array $Result += $pipelineInfo } # Export results to CSV file $Result | Export-Csv -Path $fileName -NoTypeInformation # Display completion summary Write-Host "========================================================================================================================================================================" Write-Host "Export completed successfully!" -ForegroundColor Green Write-Host "Total pipelines processed: $($Result.Count)" -ForegroundColor Yellow Write-Host "Output file: $fileName" -ForegroundColor Yellow Write-Host "========================================================================================================================================================================"