Public/Invoke-AppEnhancerAdhocQuery.ps1

function Invoke-AppEnhancerAdhocQuery {
    <#
    .SYNOPSIS
        Executes an ad hoc query against the ApplicationXtender REST API.
     
    .DESCRIPTION
        Sends a POST request to the AX API with specified index values and optional full-text search parameters.
        Returns the query result as a PowerShell object for further processing or inspection.
     
    .PARAMETER ServerUrl
        The base URL of the AX WebCore server.
     
    .PARAMETER Credential
        A PSCredential object containing the username and secure password.
     
    .PARAMETER Indexes
        An array of hashtables with Name and Value keys for index filtering.
     
    .PARAMETER FullTextValue
        Optional full-text search string.
     
    .PARAMETER QueryOperator
        Operator for full-text search (default: 0).
     
    .PARAMETER SearchType
        Type of full-text search (default: 0).
     
    .PARAMETER Thesaurus
        Whether to use thesaurus in full-text search (default: $true).
     
    .PARAMETER IncludePreviousRevisions
        Whether to include previous revisions in the query (default: $false).
     
    .PARAMETER AppId
        The ApplicationXtender App ID to query.
     
    .OUTPUTS
        PSCustomObject
        Returns a PSCustomObject containing the query results from the AX API.
        If the request fails or the response is not in the expected format, returns $null.
     
    .EXAMPLE
        $cred = Get-Credential
        $appId = 28
        $indexes = @(
            @{ Name = "Date"; Value = "07/31/2025" },
            @{ Name = "Notice Type"; Value = "Box Delinquency" }
        )
        $response = Invoke-AppEnhancerAdhocQuery -ServerUrl "https://axwebserver.local" -Credential $cred -Indexes $indexes -AppId $appId
    #>


    [OutputType([PSCustomObject])]
    param (
        [Parameter(Mandatory=$true)]
        [string]$ServerUrl,
    
        [Parameter(Mandatory=$true)]
        [PSCredential]$Credential,
    
        [Parameter(Mandatory=$true)]
        [hashtable[]]$Indexes,  # Accepts an array of @{ Name = "..."; Value = "..." }
    
        [string]$FullTextValue = "",
        [int]$QueryOperator = 0,
        [int]$SearchType = 0,
        [bool]$Thesaurus = $true,
        [bool]$IncludePreviousRevisions = $false,
    
        [Parameter(Mandatory=$true)]
        [int]$AppId
    )
    
    begin {}

    process {
        $queryUrl = "$ServerUrl/AppXtenderReST/api/AXDataSources/ApplicationXtender/AXAdhocQueryResults/$AppId"
        Write-Verbose "Constructed query URL: $queryUrl"
    
        # Convert SecureString to plain text
        $plainPassword = [Runtime.InteropServices.Marshal]::PtrToStringAuto(
            [Runtime.InteropServices.Marshal]::SecureStringToBSTR($Credential.Password)
        )
        Write-Verbose "Converted SecureString password to plain text."
    
        $cred = "$($Credential.Username):$plainPassword"
        $base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes($cred))
        Write-Verbose "Generated Base64-encoded credentials."
    
        $body = @{
            Indexes = $Indexes
            fullText = @{
                QueryOperator = $QueryOperator
                SearchType = $SearchType
                Thesaurus = $Thesaurus
                Value = $FullTextValue
            }
            IsIncludingPreviousRevisions = $IncludePreviousRevisions
        } | ConvertTo-Json -Depth 5
        Write-Verbose "Constructed request body:`n$body"
    
        $headers = @{
            "Authorization" = "Basic $base64AuthInfo"
            "Content-Type"  = "application/vnd.emc.ax+json"
        }
        Write-Verbose "Prepared request headers."
    
        try {
            Write-Verbose "Sending POST request to AX API..."
            $response = Invoke-RestMethod -Uri $queryUrl -Headers $headers -Method Post -Body $body
            Write-Verbose "Received response from AX API."
    
            if ($response -isnot [PSCustomObject]) {
                Write-Error "Unexpected response type: $($response.GetType().FullName)"
                return $null
            }
    
            return $response
        } 
        
        catch {
            Write-Error "AX Query failed: $_"
            return $null
        }
    }

    end {}
}