lib/TMQL.ps1


function Invoke-TMQLStatement {
    <#
    .SYNOPSIS
    Executes a statement against the TMQL endpoint
 
    .DESCRIPTION
    This function will execute a statement written in TM query language against the
    REST API endpoint on a TransitionManager instance
 
    .PARAMETER TMSession
    The name of the TM Session to use when executing a statement
 
    .PARAMETER Statement
    The TMQL staement to be executed
 
    .EXAMPLE
    "find Device by 'Name' ate '$Server1|$Server2' fetch 'id'" | Invoke-TMQLStatement -TMSession TMAD60
 
    .EXAMPLE
    $Statement = @"
        find Person by \
        'email' eq 'sowen@tdsi.com' \
        fetch 'id', 'email', 'firstName', 'lastName'
    "@
    Invoke-TMQLStatement -TMSession TMAD60 -Statement $Statement
 
    .OUTPUTS
    A PSCustomObject containing the results of the statement execution
    #>


    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $false, Position = 1)]
        [String]$TMSession = "Default",

        [Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $true)]
        [String]$Statement
    )

    begin {

        # Get the session configuration
        Write-Verbose "Checking for cached TMSession"
        $TMSessionConfig = $global:TMSessions[$TMSession]
        Write-Debug "TMSessionConfig:"
        Write-Debug ($TMSessionConfig | ConvertTo-Json -Depth 5)
        if (-not $TMSessionConfig) {
            throw "TMSession '$TMSession' not found. Use New-TMSession command before using features."
        }

        # Make sure we have a bearer token for the REST endpoint
        Write-Verbose "Checking for TMRestSession with bearer token"
        if (-not $TMSessionConfig.TMRestSession) {
            throw "TMSession '$TMSession' is not logged into the TransitionManager API. Use New-TMSession -Api `$true command to connect to a compatible server."
        }

        # Make sure the TM instance is v5.0.4 or greater
        Write-Verbose "Checking for compatible TransitionManager instance"
        Write-Debug "TM Version: $($TMSessionConfig.TMVersion)"
        if ($TMSessionConfig.TMVersion -lt '5.0.4') {
            throw "The TMQL endpoint is not available on TransitionManager versions below 5.0.4"
        }

        # Form the URI
        Write-Verbose "Forming the web request URI"
        $Uri = "https://$($TMSessionConfig.TMServer)/tdstm/api/tmql/statement"
    }

    process {
        try {
            Write-Verbose "Forming web request parameters"
            $RestSplat = @{
                Uri                  = $Uri
                Method               = 'GET'
                WebSession           = $TMSessionConfig.TMRestSession
                SkipHttpErrorCheck   = $true
                StatusCodeVariable   = 'StatusCode'
                SkipCertificateCheck = $TMSessionConfig.AllowInsecureSSL
                Body                 = (
                    @{
                        statement = $Statement
                        project   = $TMSessionConfig.userContext.project.id
                    } | ConvertTo-Json
                )
            }

            Write-Debug "Web Request Parameters:"
            Write-Debug ($RestSplat | ConvertTo-Json -Depth 10)
            Write-Verbose "Invoking web request"
            $Response = Invoke-RestMethod @RestSplat
            if ($StatusCode -in 200, 204) {
                $Response
            } elseif (-not [String]::IsNullOrWhiteSpace($Response)) {
                if ($Response.errors) {
                    throw $Response.errors
                }
                throw $Response
            } else {
                throw "The response status code $StatusCode does not indicate success."
            }
        } catch {
            throw "Could not execute statement: $($_.Exception.Message)"
        }
    }
}