Public/Get-DuneDeploymentTemplate.ps1

<#
.SYNOPSIS
Retrieve deployment templates.

.DESCRIPTION
Gets deployment templates. Supports parameter sets for `Name` (with optional `Version`), `Id`, and `Deployment` (pipeline input). You can request raw API output, include definitions or deleted templates, and request only the latest version of each template.

.PARAMETER Name
Filter templates by name (supports wildcards). Use the `Name` parameter set; `Version` may optionally follow.

.PARAMETER Version
Filter templates by version (used with the `Name` parameter set).

.PARAMETER Id
The GUID of the deployment template. Use the `Id` parameter set to retrieve a specific template.

.PARAMETER Deployment
A `DuneDeployment` object; returns the template referenced by the supplied deployment (pipeline input supported).

.PARAMETER Raw
If set, returns raw API objects instead of `DuneDeploymentTemplate` objects.

.PARAMETER IncludeDefinition
Include the full template definition in the returned objects.

.PARAMETER IncludeDeleted
Include deleted templates in results.

.PARAMETER Latest
If set, return only the latest version of each template name.

.EXAMPLE
PS> Get-DuneDeploymentTemplate -Name "base-template"
Returns templates matching the name `base-template`.

.EXAMPLE
PS> Get-DuneDeploymentTemplate -Id 3d8f6b5a-...
Returns the deployment template with the specified `Id`.

.EXAMPLE
PS> Get-DuneDeployment -Name "MyApp" | Get-DuneDeploymentTemplate
Pipeline example using the `Deployment` parameter set.
#>

function Get-DuneDeploymentTemplate {
    [CmdletBinding(DefaultParameterSetName = "Default")]
    param (
        [Parameter(ParameterSetName = "Name", Mandatory, Position = 0)]
        [string]$Name,

        [Parameter(ParameterSetName = "Name", Position = 1)]
        [string]$Version,

        [Parameter(ParameterSetName = "Id")]
        [guid]$Id,

        [Parameter(ParameterSetName = "Deployment", ValueFromPipeline)]
        [DuneDeployment]$Deployment,

        [Parameter()]
        [switch]$Raw,

        [Parameter()]
        [switch]$IncludeDefinition,

        [Parameter()]
        [switch]$IncludeDeleted,

        [Parameter()]
        [switch]$Latest
    )

    begin {
        Write-Debug "$($MyInvocation.MyCommand)|begin"
        $ReturnObjects = @()
        $ProcessedUrls = @()
        $BaseUri = 'deploymenttemplates'
        $Method = 'GET'
    }

    process {
        Write-Debug "$($MyInvocation.MyCommand)|process|$($PSCmdlet.ParameterSetName)"

        # Build Uri
        switch ($PSCmdlet.ParameterSetName) {
            'Id' { $Uri = '{0}/{1}' -f $BaseUri, $Id }
            'Name' {
                $Uri = $BaseUri | Add-UriQueryParam "NameILike=$Name" -ConvertWildcards
                if ($Version) { $Uri = $Uri | Add-UriQueryParam "VersionILike=$Version" -ConvertWildcards }
            }
            'Deployment' {
                if ($Deployment.Template) {
                    return $Deployment.Template
                }
                else {
                    if ($Deployment.TemplateId) {
                        $Uri = '{0}/{1}' -f $BaseUri, $Deployment.TemplateId
                    }
                    else {
                        throw "TemplateId not set on Deployment $($Deployment.Name) (Id: $($Deployment.Id))"
                    }
                }
            }
            Default { $Uri = $BaseUri }
        }
        if ($PSCmdlet.ParameterSetName -in ('Id', 'Deployment')) {
            $Uri = $Uri | Add-UriQueryParam "IncludeDefinition=1"
            $Uri = $Uri | Add-UriQueryParam "IncludeReferencedObjects=1"
        }
        if ($IncludeDeleted) {
            $Uri = $Uri | Add-UriQueryParam "IncludeDeleted=1"
        }

        # ApiCall Cache
        if ($ProcessedUrls -notcontains $Uri) {
            try {
                # ApiCall and Object conversion
                $ResultItems = Invoke-DuneApiRequest -Uri $Uri -Method $Method -ExtractItems
                $ProcessedUrls += $Uri
                $ReturnObjects += $ResultItems | ForEach-Object {
                    if ($Raw) {
                        $_
                    }
                    else {
                        if (-not $uri.Contains('/')) {
                            if ($IncludeDefinition) { Get-DuneDeploymentTemplate -Id $_.Id }
                            else { ConvertTo-DuneClassObject -Class DuneDeploymentTemplate -InputObject $_ }
                        }
                        else {
                            ConvertTo-DuneClassObject -Class DuneDeploymentTemplate -InputObject $_
                        }
                    }
                }
            }
            catch {
                throw $_
            }
        }
        else {
            Write-Debug "$($MyInvocation.MyCommand)|process|ApiCall Cache hit: DuneApiRequest for $Uri already invoked"
        }
    }

    end {
        Write-Debug "$($MyInvocation.MyCommand)|end"
        if ($uri -and -not $uri.Contains('/') -and -not $Raw) {
            if ($IncludeDefinition) {
                $ReturnObjects | ForEach-Object {
                    $_.Definition = ((Invoke-DuneApiRequest -Uri "$BaseUri/$($_.Id)/definition" -Method 'GET').Content | ConvertFrom-Json).Definition
                }
            }
            else {
                Write-Warning "Slimmed down objects are returned. Please specify IncludeDefinition param to show full objects (Definition, AllowedResourceProviders, ResourceGroupTemplates)"
            }
        }
        $ReturnObjects = $ReturnObjects | Sort-Object -Unique Id | Sort-Object -Property Name, Version
        if ($Latest) {
            $ReturnObjects = Foreach ($Name in ($ReturnObjects | Select Name -Unique).Name){
                $ReturnObjects | ? Name -in $Name | Sort-Object Version | Select -Last 1
            }
        }
        return $ReturnObjects
    }
}