SimpleAzureDevOps.psm1

$BaseUrl = $null
$Base64Auth = $null
$ApiVersion = "6.0"
$Headers = $null

function Connect-AzureDevOps
{
    [CmdletBinding()]
    param
    (
        [Parameter(Mandatory=$true, ParameterSetName = "EmailPat")]
        [Parameter(Mandatory=$true, ParameterSetName = "PSCredential")]
        [ValidateNotNullOrEmpty()]
        [string] $ServerUrl,

        [Parameter(Mandatory=$true, ParameterSetName = "PSCredential")]
        [ValidateNotNullOrEmpty()]
        [PSCredential] $Credential,

        [Parameter(Mandatory=$true, ParameterSetName = "EmailPat")]
        [ValidateNotNullOrEmpty()]
        [string] $EmailAddress,

        [Parameter(Mandatory=$true, ParameterSetName = "EmailPat")]
        [ValidateNotNullOrEmpty()]
        [string] $PAT

    )

    if ($ServerUrl -match "^https://dev.azure.com/.+$")
    {
        $ServerUrl = (($ServerUrl.Split('/')[2,3]) -join('/')) + "/"
    }

    if ($ServerUrl -notmatch "/$")
    {
        $ServerUrl = $ServerUrl + "/"
    }

    $Script:BaseUrl = $ServerURL

    if ($PSCmdlet.ParameterSetName -like "PSCredential") 
    {
        $NetworkCredential = $Credential.GetNetworkCredential()    
        $EmailAddress = $NetworkCredential.Username    
        $PAT = $NetworkCredential.Password    
    }

    $Script:Base64Auth = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $EmailAddress, $PAT)))

    $Script:Headers = @{
        Authorization = "Basic {0}" -f $Base64Auth
    }

    return @{ "BaseUrl" = $BaseUrl ; "Base64Auth" = $Base64Auth }
}

function Get-AzureDevOpsOrganizationProjects
{
    [CmdletBinding()]
    param()

    return Invoke-API -Param "_apis/projects" -Method GET
}

function Get-AzureDevOpsAgentPool
{
    [CmdletBinding()]
    param
    (
        [Parameter(Mandatory=$true, ParameterSetName = "ID")]
        [ValidateNotNullOrEmpty()]
        [string] $ID,

        [Parameter(Mandatory=$true, ParameterSetName = "Name")]
        [ValidateNotNullOrEmpty()]
        [string] $Name
    )

    $param = "_apis/distributedtask/pools"

    if ($PSCmdlet.ParameterSetName -like "ID")
    {
        $param = "$($param)/$($ID)"
    }
    else 
    {
        $param = "$($param)?poolName=$($Name)"
    }

    return Invoke-API -Param $param -Method GET
}

function Get-AzureDevOpsReleaseDefinition
{
    [CmdletBinding()]
    param
    (
        [Parameter(Mandatory=$true, ParameterSetName = "ID")]
        [Parameter(Mandatory=$true, ParameterSetName = "Name")]
        [ValidateNotNullOrEmpty()]
        [string] $ProjectName,

        [Parameter(Mandatory=$true, ParameterSetName = "ID")]
        [ValidateNotNullOrEmpty()]
        [string] $DefinitionID,

        [Parameter(Mandatory=$true, ParameterSetName = "Name")]
        [ValidateNotNullOrEmpty()]
        [string] $DefinitionName
    )

    $param = "$($ProjectName)/_apis/release/definitions"

    if ($PSCmdlet.ParameterSetName -like "ID")
    {
        $param = "$($param)/$($DefinitionID)"
    }
    else 
    {
        $param = "$($param)?searchText=$($DefinitionName)"
    }

    return Invoke-API -Param $param -Method GET -VSRM
}

function Get-AzureDevOpsReleaseStatus
{
    [CmdletBinding()]
    param
    (
        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [string] $ProjectName,

        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [string] $ReleaseID
    )

    $param = "$($ProjectName)/_apis/Release/releases/$($ReleaseID)"
    return Invoke-API -Param $param -Method GET -VSRM
}

function Get-AzureDevOpsDeploymentGroup
{
    [CmdletBinding()]
    param
    (
        [Parameter(Mandatory=$true, ParameterSetName = "ID")]
        [Parameter(Mandatory=$true, ParameterSetName = "Name")]
        [ValidateNotNullOrEmpty()]
        [string] $ProjectName,

        [Parameter(Mandatory=$true, ParameterSetName = "ID")]
        [ValidateNotNullOrEmpty()]
        [string] $ID,

        [Parameter(Mandatory=$true, ParameterSetName = "Name")]
        [ValidateNotNullOrEmpty()]
        [string] $Name
    )

    $param = "$($ProjectName)/_apis/distributedtask/deploymentgroups"

    if ($PSCmdlet.ParameterSetName -like "ID")
    {
        $param = "$($param)/$($ID)"
    }
    else 
    {
        $param = "$($param)?name=$($Name)"
    }

    return Invoke-API -Param $param -Method GET
}

function New-AzureDevOpsReleaseQueue
{
    [CmdletBinding()]
    param
    (
        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [string] $ProjectName,

        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [string] $DefinitionID
    )

    $body = @{
        definitionId = $DefinitionID
    }

    $param = "$($ProjectName)/_apis/Release/releases"
    return Invoke-API -Param $param -Method POST -Body $body -VSRM
}

function Set-AzureDevOpsAPIVersion
{
    [CmdletBinding()]
    param
    (
        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [string] $Version
    )

    $Script:ApiVersion = $Version
}

function Invoke-API
{
    [CmdletBinding(DefaultParameterSetName = "Getters")]
    param
    (
        [Parameter(Mandatory=$true, ParameterSetName = "Getters")]
        [Parameter(Mandatory=$true, ParameterSetName = "Others")]
        [ValidateNotNullOrEmpty()]
        [string] $Param,

        [Parameter(Mandatory=$true, ParameterSetName = "Others")]
        [ValidateNotNullOrEmpty()]
        $Body,

        [Parameter(Mandatory=$true, ParameterSetName = "Getters")]
        [Parameter(Mandatory=$true, ParameterSetName = "Others")]
        [ValidateSet("GET", "POST", "PUT")]
        [string] $Method,

        [Parameter(Mandatory=$false, ParameterSetName = "Getters")]
        [Parameter(Mandatory=$false, ParameterSetName = "Others")]
        [switch] $VSRM
    )

    $requestUri = $Script:BaseUrl + $Param 

    $apiVersion = "api-version=$($ApiVersion)"
    $apiChar = "?"
    
    if ($requestUri -match "[?]")
    {
        $apiChar = "&"
    }
    
    $requestUri = "$($requestUri)$($apiChar)$($apiVersion)"

    if ($VSRM) 
    {   
        $requestUri = "vsrm.$($requestUri)" 
    }

    $restMethodParam = @{
        Uri     = "https://$($requestUri)"
        Headers = $Script:Headers
        Method  = $Method
        ContentType = "application/json"
    }

    if ($Method -notmatch "GET") { $restMethodParam["Body"] = ($Body | ConvertTo-Json) }

    $response = Invoke-RestMethod @restMethodParam
    return $response
}