public/Get-AzureDevOpsArtifacts.ps1




Function Get-AzureDevOpsArtifacts {
<#
    .SYNOPSIS
    Gets a a list of artifacts belonging to a specific package in a specific feed.
     
    .DESCRIPTION
    Gets a a list of artifacts belonging to a specific package in a specific feed. Only organization-scoped feeds are supported for now.
 
    .EXAMPLE
     
     
    .PARAMETER Organization
    The name of the Azure DevOps organization
     
    .PARAMETER Feed
    The feed containing the package.
 
    .PARAMETER Package
    The package containing the artifacts. Note, the user must have read access to the specific package.
 
    .PARAMETER AzureDevOpsAccessToken
    The access token to use for accessing the artifacts. Note, this requires Read on packaging for the access token.
    
    .OUTPUTS
    All versions of the package incl. a url for downloading the file.
     
    .LINK
    https://github.com/DennisWagner/SQLServerDevOpsTools
     
    .NOTES
    Written by (c) Dennis Wagner Kristensen, 2021 https://github.com/DennisWagner/SQLServerDevOpsTools
    This PowerShell script is released under the MIT license http://www.opensource.org/licenses/MIT
#>



    Param (
                [Parameter(Mandatory=$true)]
                [string]
                $Organization,
                [Parameter(Mandatory=$true)]
                [string]
                $Feed,
                [Parameter(Mandatory=$true)]
                [string]
                $Package,
                [Parameter(Mandatory=$false)]
                [string]
                $AzureDevOpsAccessToken
    )
    BEGIN {
        $AzureDevOpsAuthenicationHeader = @{Authorization = 'Basic ' + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$($AzureDevOpsAccessToken)")) }

    }

    PROCESS {

        ## TODO: Add support for project-specific feeds https://docs.microsoft.com/en-us/azure/devops/artifacts/feeds/project-scoped-feeds?view=azure-devops
        

        # Get the feed
        $uri = "https://feeds.dev.azure.com/$($Organization)/_apis/packaging/feeds"
        Write-Verbose "Locating feeds."
        $response = Invoke-WebRequest -Uri $uri -Method get -Headers $AzureDevOpsAuthenicationHeader
        
        If ($response.StatusCode -eq 203) {
            Throw "There was an error accessing Azure DevOps: Error: $($response.StatusCode) $($response.StatusDescription). Response from Azure DevOps: $($response.Content)"
        } elseif ($response.StatusCode -ne 200) {
            Throw "There was an unknown error accessing Azure DevOps at URL: $($uri): Error: $($response.StatusCode) $($response.StatusDescription)."
        }

        $feeds = $response.Content | ConvertFrom-Json

        If ($feeds.count -eq 0) {
            Throw "Unable to locate any feeds in the Azure DevOps organization: $Organization"
        }

        $CurrentFeed = $feeds.value | Where-Object Name -eq $Feed  

        If (-not $CurrentFeed) {
            Throw "Unable to locate feed: $Feed at: $uri"
        } else {
            # Locate package
            If ($CurrentFeed._links.packages.href) {
                $uri = $CurrentFeed._links.packages.href
                Try {
                    Write-Verbose "Locating packages."
                    $response = Invoke-WebRequest -Uri $uri -Method get -Headers $AzureDevOpsAuthenicationHeader
                
                } Catch {

                    Throw "An unexpected error occurred while getting packages for feed: $($_.Name). Error: $($_.Message)"
                }
            } else {
                Throw "Unable to locate package: $Package in feed: $Feed at: $uri"
            }

            $packages = $response.Content | ConvertFrom-Json

            If ($packages.count -eq 0) {
                Throw "Unable to locate any packages in feed: $Feed in the Azure DevOps organization: $Organization"
            }

            $CurrentPackage = $packages.value | Where-Object Name -eq $Package 

            If ( -not $CurrentPackage) {
                Throw "Unable to locate the package: $Package in the feed: $Feed at: $uri"
            }

            If ($CurrentPackage._links.versions.href) {
                
                $uri = $CurrentPackage._links.versions.href

                Try {
                    Write-Verbose "Locating versions."
                    $response = Invoke-WebRequest -Uri $uri -Method get -Headers $AzureDevOpsAuthenicationHeader

                    $Versions = $response.Content | ConvertFrom-Json         
                } Catch {

                    Throw "An unexpected error occurred while getting versions for feed: $($_.Name). Error: $($_.Message)"
                }

                ForEach ($version in $Versions.value ) {
                New-Object PSObject -Property @{
                    Feed = $Feed
                    Package =  $Package
                    Version = $version.version
                    isLatest = $version.isLatest
                    isListed = $version.isListed
                    PublishDate = $version.PublishDate
                    Url = "https://pkgs.dev.azure.com/$($Organization)/_apis/packaging/feeds/$Feed/nuget/packages/$Package/versions/$($version.version)/content?api-version=6.0"
                }
            
            }

            } else {
                Throw "Unable to locate package: $Package in feed: $Feed at: $uri"
            }
        }
    }
    END {
    
    }
}