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 {} } |