PowerAppEnhancer.psm1

function New-AppEnhancerPdfBatch {
    <#
    .SYNOPSIS
        This script creates a new batch in Application Enhancer for PDFs.
 
    .NOTES
        Name: New-AppEnhancerBatch
        Author: Bruce Stump
 
    .DESCRIPTION
        Uploading applications into OpenText Application Enhancer is a two step process; create a
        new batch, then index the document. This script creates a batch for a PDF in preparation
        for indexing. All parameters are mandatory for script.
 
        -FilePath: Path to PDF.
        -serverURL: Server URL.
        -Cred: Credential Object, must be a PSCustomObject.
        -dsn: Database Name.
        -appid: Application ID.
 
    .EXAMPLE
        New-AppEnhancerBatch -FilePath $pdfFilePath -serverUrl $serverUrl
        -Cred $credential -dsn $database -appid $AppID
    #>


    [CmdletBinding()]

    param(
        [Parameter(Mandatory=$true)]
        [string]$FilePath,
        [Parameter(Mandatory=$true)]
        [string]$serverUrl,
        [Parameter(Mandatory=$true)]
        [pscredential]$Cred,
        [Parameter(Mandatory=$true)]
        [string]$dsn,
        [Parameter(Mandatory=$true)]
        [string]$appid,
        [Parameter(Mandatory=$true)]
        [string]$BatchName,
        [Parameter(Mandatory=$true)]
        [string]$BatchDescription
    )

    begin{
        Add-Type -AssemblyName "System.Net.Http"

        $Username = $Cred.UserName
        $Password = $cred.GetNetworkCredential().password 
    }

    process {
        try {
            # === Encode credentials for Basic Auth ===
            $pair = $Username + ':' + $Password
            $bytes = [System.Text.Encoding]::ASCII.GetBytes($pair)
            $base64 = [Convert]::ToBase64String($bytes)
            $authHeader = "Basic $base64"
 
            # Create Endpoint
            $endPoint = "$serverUrl/AppXtenderRest/api/AXDataSources/$dsn/axbatches/$appid"
 
            # Create JSON content (as a string)
            $JsonPayload = @{
                "Name" = $BatchName
                "Description" = $BatchDescription
                "Private" = $false
            } | ConvertTo-Json -Depth 3
 
            # Prepare PDF file content
            $FileStream = [System.IO.File]::OpenRead($FilePath)
            $FileContent = New-Object System.Net.Http.StreamContent($FileStream)
            $FileContent.Headers.ContentType = [System.Net.Http.Headers.MediaTypeHeaderValue]::Parse("application/pdf")
 
            # Prepare JSON content
            $JsonContent = New-Object System.Net.Http.StringContent($JsonPayload, [System.Text.Encoding]::UTF8, "application/vnd.emc.ax+json")
 
            # Create multipart form content
            $Form = New-Object System.Net.Http.MultipartFormDataContent
 
            # Add PDF file to form (use the correct form field name expected by the API)
            $Form.Add($FileContent, "bin", [System.IO.Path]::GetFileName($FilePath))
 
            # Add JSON to form (the name "metadata" is an example, adjust as needed)
            $Form.Add($JsonContent, "data")
 
            # Create HTTP client
            $HttpClient = New-Object System.Net.Http.HttpClient
 
            # === Send request with Basic Auth ===
            $HttpClient.DefaultRequestHeaders.Authorization = $authHeader
 
            # Send the POST request
            $response = $HttpClient.PostAsync($endPoint, $Form).Result
 
            # Read the response
            $responseContent = $response.Content.ReadAsStringAsync().Result
            Write-Output "Status Code: $($response.StatusCode)"
            Write-Output "Response: $responseContent"   
        }

        catch {
            $_.Exception.Message
        }
    }

    end {
        # Clean up
        $FileStream.Dispose()
    }
}

function Add-AppEnhancerBatchIndex {
    <#
    .SYNOPSIS
        This script adds indexes to batches.
 
    .NOTES
        Name: Add-AppEnhancerIndex
        Author: Bruce Stump
 
    .DESCRIPTION
        Adds indexes to batches in Application Enhancer after the batches have been created.
 
    .EXAMPLE
        Add-AppEnhancerIndex -serverUrl $ServerUrl -AppEnhancerCred $Cred -AppId ApplicationID
        -FromBatch $BatchId
    #>


    param (
        [Parameter(Mandatory=$true)]
        [pscredential]$AppEnhancerCred,
        [Parameter(Mandatory=$true)]
        [string]$serverUrl,
        [Parameter(Mandatory=$true)]
        [string]$AppId,
        [Parameter(Mandatory=$true)]
        [string]$FromBatch,
        [string]$EndPoint = 'AppXtenderRest/api/AXDataSources/ApplicationXtender/AXDocs',
        [Parameter(Mandatory=$true)]
        [string]$StringIndex
    )

    begin {
        # Load the necessary assembly
        Add-Type -AssemblyName System.Net.Http

        # Define the API endpoint
        $apiEndpoint = "$serverUrl/$EndPoint/$AppId"

        # Application Enhancer Credential Object
        $cred = $AppEnhancerCred.UserName + ':' + $AppEnhancerCred.GetNetworkCredential().password
    }

    process {
        # Convert credentials to Base64 for Basic Authentication
        $base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes($cred))

        $authHeader = "Basic $base64AuthInfo"

        # Create an instance of HttpClient
        $httpClient = New-Object System.Net.Http.HttpClient

        # Set the Accept header
        $httpClient.DefaultRequestHeaders.Accept.Add([System.Net.Http.Headers.MediaTypeWithQualityHeaderValue]::new("application/vnd.emc.ax+json"))

        # Define the number of times to repeat the hash table
        $repeatCount = (Get-AppEnhancerApplicationFields -AppId $AppId -serverUrl $serverUrl -Cred $AppEnhancerCred).entries.count

        # Initialize an empty array to store the repeated hash tables
        $repeatedValues = @()

        # Use a loop to repeat the hash table
        for ($i = 1; $i -le $repeatCount; $i++) {
            $repeatedValues += @{
            FieldID = "field$i"
            FieldValue = ""
            }
        }
    
        # Define the data
        $data = @{
            TargetDoc = @{
                ID = 0
            }
            NewIndex = @{
                indexid = 0
                values = @(
                    $repeatedValues
                )
            }
            FromBatch = @{
                ID = $FromBatch
            }
            BatchPageNum = 0
            IngoreDuplicateIndex = $true
            IgnoreDlsViolation = $false
        }

        $index = $StringIndex.split('|')

        $indexFields = @()
        
        for ($i = 0;$i -le $index.count-1;$i++) {
            $indexFields += @{ FieldID = $data.NewIndex.Values[$i].FieldID; FieldValue = $index[$i]}
        }

        $newRecords = $indexFields
 
        # Replace the existing records with the new records
        $data.NewIndex.values = $newRecords

        # Convert the data to JSON
        $jsonData = $data | ConvertTo-Json -Depth 3

        # Create the content for the request
        $content = New-Object System.Net.Http.StringContent($jsonData, [System.Text.Encoding]::UTF8, "application/vnd.emc.ax+json")

        # === Send request with Basic Auth ===
        $HttpClient.DefaultRequestHeaders.Authorization = $authHeader

        # Send the POST request
        $response = $httpClient.PostAsync($apiEndpoint, $content).Result

        $response
    }

    end {}
}

function Get-AppEnhancerApplicationFields {
    <#
    .SYNOPSIS
        This script gets field information for specific application.
 
    .NOTES
        Name: Get-AppEnhancerApplicationFields
        Author: Bruce Stump
 
    .DESCRIPTION
        This script gets field information for specific application in Application
        Enhancer.
 
    .EXAMPLE
        Get-AppEnhancerApplicationFields -AppId $ApplicationId -Cred $credentials -serverUrl $serverUrl
    #>


    param (
        [Parameter(Mandatory=$true)]
        [string]$AppId,
        [Parameter(Mandatory=$true)]
        [pscredential]$Cred,
        [Parameter(Mandatory=$true)]
        [string]$serverUrl
    )

    begin {
        # Define your credentials
        $username = $Cred.UserName
        $password = $Cred.GetNetworkCredential().password
    }

    process {
        # Convert credentials to Base64 for Basic Authentication
        $pair = $username + ':' + $password
        $bytes = [System.Text.Encoding]::ASCII.GetBytes($pair)
        $base64 = [Convert]::ToBase64String($bytes)
        $authHeader = "Basic $base64"

        # Define headers with Basic Authentication
        $headers = @{
            "Authorization" = $authHeader
            "Content-Type"  = "application/json"
        }

        # Define the URL to get the list of applications
        $applicationsUrl = "$serverUrl/AppXtenderReST/api/AXDataSources/ApplicationXtender/axappfields/$AppId"

        # Retrieve the list of applications
        Invoke-RestMethod -Uri $applicationsUrl -Method Get -Headers $headers
    }

    end {}
}

function New-AppEnhancerTxtBatch {
    <#
    .SYNOPSIS
        This script creates a new batch for text documentsin Application Enhancer
        for PDFs.
 
    .NOTES
        Name: New-AppEnhancerTxtBatch
        Author: Bruce Stump
 
    .DESCRIPTION
        Uploading applications into OpenText Application Enhancer is a two step process; create a
        new batch, then index the document. This script creates a batch for a text document in
        preparation for indexing. All parameters are mandatory for script.
 
        -inputFilePath: File Path to text file to be imported.
        -outputFilePath: File Path to encoded text file, encoded inputFilePath.
        -serverURL: Server URL.
        -Cred: Credential Object, must be a PSCustomObject.
        -dsn: Database Name.
        -appid: Application ID.
        -BatchName: Name of Batch that will be created in App Enhancer.
        -BatchDescription: Description of Batch created in App Enhancer.
 
    .EXAMPLE
        New-AppEnhancerTxtBatch -inputFilePath $txtFilePath -outputFilePath $outFilePath
        -serverUrl $serverUrl -Cred $credential -dsn $database -appid $AppID
        -BatchName $BatchName -BatchDescription $BatchDescription
    #>


    [CmdletBinding()]

    param (
        [Parameter(Mandatory=$true)]
        [pscredential]$Cred,
        [Parameter(Mandatory=$true)]
        [string]$serverUrl,
        [Parameter(Mandatory=$true)]
        [string]$dsn,
        [Parameter(Mandatory=$true)]
        [string]$appid,
        [Parameter(Mandatory=$true)]
        [string]$BatchName,
        [Parameter(Mandatory=$true)]
        [string]$BatchDescription,
        [Parameter(Mandatory=$true)]
        [string]$inputFilePath,
        [Parameter(Mandatory=$true)]
        [string]$outputFilePath
    )

    begin {
        # Define your credentials
        $username = $Cred.UserName
        $password = $cred.GetNetworkCredential().password
    }
 
    process {
        # Convert credentials to Base64 for Basic Authentication
        $pair = $username + ':' + $password
        $bytes = [System.Text.Encoding]::ASCII.GetBytes($pair)
        $base64 = [Convert]::ToBase64String($bytes)
        $authHeader = "Basic $base64"
        #$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(($pair)))
 
        # Create Endpoint
        $endPoint = "$serverUrl/AppXtenderRest/api/AXDataSources/$dsn/axbatches/$appid"
 
        # Create boundary, delimeter between different sections of data
        $boundary = [System.Guid]::NewGuid().ToString()
 
        # Header need for Authorization
        $headers = @{
            "Authorization" = $authHeader
            "Accept" = "application/vnd.emc.ax+json"
            "Content-Type" = "multipart/form-data;boundary=$boundary"
        }
 
        # Batch information
        $batchData = @{
            "Name" = $BatchName
            "Description" = $BatchDescription
            "Private" = $false
        }
 
        # Read the content of the input file
        $content = Get-Content -Path $inputFilePath -Raw
 
        # Write the content to the output file with UTF-8 encoding
        [System.IO.File]::WriteAllText($outputFilePath, $content, [System.Text.Encoding]::UTF8)
 
        # Read bytes of text file with utf-8 encoding
        $fileContent = [System.IO.File]::ReadAllBytes($outputFilePath)
 
        $body = "--$boundary`r`n"
        $body += "Content-Type: application/vnd.emc.ax+json; charset=utf-8`r`n"
        $body += "Content-Disposition: form-data; name=`"data`"`r`n`r`n"
        $body += (ConvertTo-Json $batchData) + "`r`n"
        $body += "--$boundary`r`n"
        $body += "Content-Type: text/plain`r`n"
        $body += "Content-Disposition: form-data; name=`"bin`"; filename=`"test2_utf8.txt`"; filename*=utf-8''test2_utf8.txt`r`n`r`n"
 
        # Code to use for encryption
        $CODEPAGE = "iso-8859-1" # alternatives are ASCII, UTF-8, iso-8859-1
 
        # Get Encoding for Codepage
        $enc = [System.Text.Encoding]::GetEncoding($CODEPAGE)
 
        # Get Encrypted File.
        $fileEnc = $enc.GetString($fileContent)
 
        # Check for BOM and remove it if present
        if ($fileEnc.StartsWith([System.Text.Encoding]::UTF8.GetString([byte[]](0xEF, 0xBB, 0xBF)))) {
            $fileEnc = $fileEnc.Substring(3)
        }
 
        $body += $fileEnc + "`r`n"
 
        $body += "--$boundary--"
 
        Invoke-RestMethod -Uri $endpoint -Method Post -Headers $headers -Body $body
    }

    end {}
}

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 {}
}
function Get-AppEnhancerDocumentIndex {
    <#
    .SYNOPSIS
        Retrieves the index values for a specific document in ApplicationXtender.
     
    .DESCRIPTION
        Sends a GET request to the ApplicationXtender REST API to retrieve index metadata
        for a document identified by its DocId and AppId. The function authenticates using
        Basic Authentication and returns the document index information as a PowerShell object.
     
    .PARAMETER ServerUrl
        The base URL of the AX WebCore server (e.g., https://yourserver.domain.local).
     
    .PARAMETER Credential
        A PSCredential object containing the username and secure password used for Basic Authentication.
     
    .PARAMETER DocId
        The unique document ID within the specified ApplicationXtender application.
     
    .PARAMETER AppId
        The ApplicationXtender App ID where the document resides.
     
    .OUTPUTS
        [PSCustomObject]
        Returns a PSCustomObject containing the document index values.
        If the request fails or the response is not in the expected format, returns $null.
     
    .EXAMPLE
        $cred = Get-Credential
        $docId = '12345'
        $appId = 28
        $response = Get-AppEnhancerDocumentIndex -ServerUrl "https://axwebserver.local" -Credential $cred -DocId $docId -AppId $appId -Verbose
     
        This example retrieves the index values for document ID 12345 in Application ID 28 using the provided credentials.
     
    .NOTES
        Author: Bruce Stump
        Last Updated: August 19, 2025
        Requires: PowerShell 5.1 or later, ApplicationXtender REST API access
    #>


    [CmdletBinding()]
    [OutputType([PSCustomObject])]
    param (
        [Parameter(Mandatory=$true)]
        [string]$ServerUrl,
        
        [Parameter(Mandatory=$true)]
        [PSCredential]$Credential,
        
        [Parameter(Mandatory=$true)]
        [int]$DocId,
        
        [Parameter(Mandatory=$true)]
        [int]$AppId
    )

    begin {}

    process {
        # Convert SecureString to plain text
        $plainPassword = [Runtime.InteropServices.Marshal]::PtrToStringAuto(
            [Runtime.InteropServices.Marshal]::SecureStringToBSTR($Credential.Password)
        )
    
        $cred = "$($Credential.Username):$plainPassword"
        $base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes($cred))
    
        $queryUrl = "$ServerUrl/AppXtenderReST/api/AXDataSources/ApplicationXtender/axapps/$AppId/axdocindexes/$DocId"
    
        $headers = @{
            "Authorization" = "Basic $base64AuthInfo"
            "Content-Type"  = "application/vnd.emc.ax+json"
        }

        try {
            Write-Verbose "Sending GET request to: $queryUrl"
            $response = Invoke-RestMethod -Uri $queryUrl -Headers $headers -Method Get
    
            return $response
        } 
        
        catch {
            Write-Error "Failed to retrieve document index: $($_.Exception.Message)"
            return $null
        }
    }

    end {}
}
function Update-AppEnhancerDocumentIndex {
    <#
    .SYNOPSIS
        Updates a specific index field of a document in ApplicationXtender using the REST API.
 
    .DESCRIPTION
        This function authenticates to the ApplicationXtender REST API using basic authentication
        and updates a specified index field for a given document within a specific application.
 
    .PARAMETER ServerUrl
        The base URL of the ApplicationXtender REST API server (e.g., https://yourserver.domain.com).
 
    .PARAMETER Credential
        A PSCredential object containing the username and password for authentication.
 
    .PARAMETER DocId
        The ID of the document whose index is to be updated.
 
    .PARAMETER AppId
        The ID of the ApplicationXtender application containing the document.
 
    .PARAMETER IndexId
        The ID of the index field to update.
 
    .EXAMPLE
        $cred = Get-Credential
        $fields = @(
            @{ FieldID = "field1"; FieldValue = "4860012" }
            @{ FieldID = "field4"; FieldValue = "07/31/2025" }
            @{ FieldID = "field5"; FieldValue = "Box Delinquency Notice" }
        )
        $docId = '1234'
        $appId = '5'
        $indexId = '2'
 
        Update-AppEnhancerDocumentIndex -ServerUrl "https://axwebserver.local" `
            -Credential $cred `
            -DocId $docId `
            -AppId $appId `
            -IndexId $indexId `
            -FieldUpdates $fields
 
        This example updates multiple index fields for document ID 1234 in application ID 5 using the provided credentials and field values.
 
    .NOTES
        Author: Bruce Stump
        Date: August 2025
        Requires: PowerShell 5.1+, ApplicationXtender REST API access
    #>


    [CmdletBinding(SupportsShouldProcess=$true)]
    param (
        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [string]$ServerUrl,
        
        [Parameter(Mandatory=$true)]
        [ValidateNotNull()]
        [PSCredential]$Credential,
        
        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [string]$DocId,
        
        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [string]$AppId,

        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [string]$IndexId,

        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [hashtable[]]$FieldUpdates
    )

    begin {}

    process {
        Write-Verbose "Starting Update-AppEnhancerDocumentIndex for DocId '$DocId', AppId '$AppId', IndexId '$IndexId'."

        foreach ($field in $FieldUpdates) {
            if (-not ($field.ContainsKey('FieldID') -and $field.ContainsKey('FieldValue'))) {
                throw "Each item in -FieldUpdates must contain 'FieldID' and 'FieldValue'."
            }
        }
    
        # Authentication
        Write-Verbose "Preparing authentication headers."

        if ([string]::IsNullOrWhiteSpace($Credential.UserName)) {
            throw "Credential username cannot be empty."
        }

        # Convert SecureString to plain text
        $plainPassword = [Runtime.InteropServices.Marshal]::PtrToStringAuto(
            [Runtime.InteropServices.Marshal]::SecureStringToBSTR($Credential.Password)
        )

        $cred = "$($Credential.Username):$plainPassword"
        $base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes($cred))

        $queryUrl = "$ServerUrl/AppXtenderReST/api/AXDataSources/ApplicationXtender/axapps/$AppId/axdocindexes/$DocId/$IndexId"
        Write-Verbose "Constructed query URL: $queryUrl"

        $headers = @{
            "Authorization" = "Basic $base64AuthInfo"
            "Content-Type"  = "application/vnd.emc.ax+json"
        }

        $documentsToUpdate = @(
            @{
                DocId = $DocId
                Values = $FieldUpdates
            }
        )

        $body = @{
            values = $documentsToUpdate[0].Values
        } | ConvertTo-Json -Depth 5

        Write-Verbose "Request body prepared: $body"

        try {
            Write-Verbose "Sending PUT request to ApplicationXtender API..."
            if ($PSCmdlet.ShouldProcess("Document ID $DocId in App ID $AppId", "Update index fields")) {
                $response = Invoke-RestMethod -Uri $queryUrl -Headers $headers -Method Put -Body $body -ErrorAction Stop
                Write-Verbose "Update successful."
                return $response
            } 
            
            else {
                Write-Verbose "WhatIf: Skipped update for Document ID $DocId in App ID $AppId."
            }
        }   
        
        catch {
            Write-Error "Failed to update document index: $_"
        }
    }

    end {}
}