Public/Common.ps1

function Invoke-TMRestMethod {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true, ParameterSetName = 'byApi')][string] $Api,
        [Parameter(Mandatory = $true, ParameterSetName = 'byUri') ][string] $Uri,
        [Parameter(Mandatory = $true)][string] $Method,
        [Parameter(Mandatory = $false)][hashtable] $BodyParams,
        [Parameter(Mandatory = $false)][string] $ApiParams,
        [Parameter(Mandatory = $false)][psobject] $TMSession = 'Default'
    )

    begin {
        if ($PSCmdlet.ParameterSetName -eq 'byUri') {
            $pattern = '/api/([^/?]+)'
            if ($uri -match $pattern) {
                $api = $matches[1]
                Write-Verbose "API Name: $api"
            } else {
                Write-Verbose 'No API name found.'
            }
        }

        $TMSession = Get-TMSession $TMSession

        $Body = @{
            project = $TMSession.UserContext.Project.Id
        }
        if ( $PSBoundParameters.ContainsKey('BodyParams')) {
            $BodyParams.Keys.foreach({$Body[$_] = $BodyParams[$_]})
        }
        if ( $PSBoundParameters.ContainsKey('ApiPArams') ) {
            $Api = [string]::Concat($Api, '?', $ApiParams)
        }

        $RestSplat = @{
            Uri                  = 'https://{0}/tdstm/api/{1}' -f $TMSession.TMServer, $Api
            Method               = $Method
            WebSession           = $TMSession.TMRestSession
            StatusCodeVariable   = 'StatusCode'
            SkipHttpErrorCheck   = $true
            SkipCertificateCheck = $TMSession.AllowInsecureSSL
            Body                 = $Body | ConvertTo-Json -EnumsAsStrings -Compress
        }
    }

    process {
        $response = Invoke-RestMethod @RestSplat
        if ($StatusCode -ne 200) {
            throw "Status Code $StatusCode does not indicate success. Response: $response"
        }
        return $response
    }
}