psAzD.psm1

Set-StrictMode -Version latest -Verbose

class AzDDefaultParameters {
    static [string] $DefaultOrganization = $env:AzD_ORGANIZATION
    static [string] $DefaultToken        = $env:AzD_PAT
    static [string] $DefaultProject      = $env:AzD_PROJECT
}

function Set-AzDDefaultParameters {
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseDeclaredVarsMoreThanAssignments", "")]
    [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = "Low")]
    param(
        [Parameter(Mandatory = $true, Position = 2, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
        [string] $Project,

        [Parameter(Mandatory = $true, Position = 1)]
        [string] $Organization,

        [Parameter(Mandatory = $true, Position = 3)]
        [string] $PersonalAccessToken
    )
    DynamicParam {
        $dp = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary

        $ParameterName = 'Level'
        # Create the collection of attributes
        $AttributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute]
        # Create and set the parameters' attributes
        $ParameterAttribute = New-Object System.Management.Automation.ParameterAttribute
        $ParameterAttribute.Mandatory = $false
        $ParameterAttribute.HelpMessage = "Set the default parameters to work with the module on ease."
        # Add the attributes to the attributes collection
        $AttributeCollection.Add($ParameterAttribute)
        # Generate and set the ValidateSet only on Windows Machine
        $arrSet = "Process", "User", "Machine"
        $ValidateSetAttribute = New-Object System.Management.Automation.ValidateSetAttribute($arrSet)
        # Add the ValidateSet to the attributes collection
        $AttributeCollection.Add($ValidateSetAttribute)
        # Create and return the dynamic parameter
        $RuntimeParameter = New-Object System.Management.Automation.RuntimeDefinedParameter($ParameterName, [string], $AttributeCollection)
        $dp.Add($ParameterName, $RuntimeParameter)

        return $dp
    }

    begin {
        $Level = $PSBoundParameters[$ParameterName]
    }

    process {
        if ($pscmdlet.ShouldProcess($Project, "Set-AzDDefaultParameters") -and 
        $pscmdlet.ShouldProcess($Organization, "Set-AzDDefaultParameters") -and 
        $pscmdlet.ShouldProcess($PersonalAccessToken, "Set-AzDDefaultParameters")) {

            if (-not $Level) {
                $Level = "Process"
            }
            $env:AzD_PROJECT = $Project
            $env:AzD_ORGANIZATION = $Organization
            $env:AzD_PAT = $PersonalAccessToken
            [AzDDefaultParameters]::DefaultProject = $Project
            [AzDDefaultParameters]::DefaultOrganization = $Organization
            [AzDDefaultParameters]::DefaultToken = $PersonalAccessToken
            [System.Environment]::SetEnvironmentVariable("AzD_PROJECT", $Project, $Level)
            $Global:PSDefaultParameterValues["*-AzD*:ProjectName"] = $Project
            [System.Environment]::SetEnvironmentVariable("AzD_ORGANIZATION", $Organization, $Level)
            $Global:PSDefaultParameterValues["*-AzD*:OrganizationName"] = $Organization
            [System.Environment]::SetEnvironmentVariable("AzD_PAT", $PersonalAccessToken, $Level)
            $Global:PSDefaultParameterValues["*-AzD*:AzureDevOpsToken"] = $PersonalAccessToken

        }        
    }
}

function Get-AzDOrganizationList {
    [CmdletBinding()]
    param (
        [string]$OrganizationName,
        [string]$AzureDevOpsToken,
        [string]$ApiVersion = "5.0-preview.1"
    )
    
    begin {
        #region variables

        $result = @()
        $url = "https://dev.azure.com/{0}/_apis/Contribution/HierarchyQuery?api-version={1}" -f $OrganizationName, $ApiVersion
        $personalAccessToken = @{
            Authorization = 'Basic ' + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$($AzureDevOpsToken)"))
        }
        $body = @"
        {
            "contributionIds": ["ms.vss-features.my-organizations-data-provider"],
            "dataProviderContext":
                {
                    "properties":{}
                }
        }
"@

        #endregion variables

    }
    
    process {
        try {
            
            Write-Verbose "Fetching list of Organizations.. "

            $response = Invoke-RestMethod `
                -Method Post `
                -Uri $url `
                -Headers $personalAccessToken `
                -Body $body `
                -ContentType "application/json"

            $result += $response.dataProviders.'ms.vss-features.my-organizations-data-provider'.organizations
        }
        catch {
            Write-Host $_ -ForegroundColor Red
        }
    }
    
    end {
        return $result
    }
}