lib/TMQL.ps1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126

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 (([Int]$TMSessionConfig.TMVersion.Split('.')[0] -eq 5) -and ([Int]$TMSessionConfig.TMVersion.Split('.')[2] -lt 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"
            ## Create the Field Settings body, differs for TM separate TM versions
            $TMVersion = [Version]::parse($TMSessionConfig.TMVersion)
            if ((($TMVersion.Major -eq 5) -and ($TMVersion -ge '5.0.4')) -or
                (($TMVersion.Major -eq 6 -and $TMVersion -ge '6.0.0.2'))) {

                $RestSplat = @{
                    Uri                = $Uri
                    Method             = 'GET'
                    WebSession         = $TMSessionConfig.TMRestSession
                    Body               = (@{
                            statement = $Statement
                            project   = $TMSessionConfig.userContext.project.id
                        } | ConvertTo-Json)
                    SkipHttpErrorCheck = $true
                    StatusCodeVariable = 'StatusCode'
                }
            }
            else {

                $RestSplat = @{
                    Uri                = $Uri
                    Method             = 'GET'
                    WebSession         = $TMSessionConfig.TMRestSession
                    Body               = (@{
                            statement = $Statement
                        } | ConvertTo-Json)
                    SkipHttpErrorCheck = $true
                    StatusCodeVariable = 'StatusCode'
                }
            }
            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)"
        }
    }
}