Private/New-VaasSearchQuery.ps1
<# .SYNOPSIS Build body for various vaas api calls .DESCRIPTION Build body for various api calls, typically for searching, eg. certificates, logs. .PARAMETER Filter Array or multidimensional array of fields and values to filter on. Each array should be of the format @('operator', @(field, comparison operator, value), @(field2, comparison operator2, value2)). Nested filters are supported. For a complete list of comparison operators, see https://docs.venafi.cloud/api/about-api-search-operators/. .PARAMETER Order Array or multidimensional array of fields to Order on. Each array should be of the format @(field, asc/desc). If just the field name is provided, ascending will be used. .EXAMPLE Read-VaasLog -Filter @('and', @('authenticationType', 'eq', 'NONE')) Filter log results .EXAMPLE Read-VaasLog -Filter @('and', @('authenticationType', 'eq', 'NONE')) -First 5 Get first 5 entries of filtered log results .EXAMPLE Read-VaasLog -Filter @('and', @('activityDate', 'gt', (get-date).AddMonths(-1)), @('or', @('userId', 'eq', 'ab0feb46-8df7-47e7-8da9-f47ab314f26a'), @('userId', 'eq', '933c28de-6352-46f3-bc12-bd96077e8eae'))) Advanced filtering of results. This filter will find log entries by 1 of 2 people within the last month. .EXAMPLE Read-VaasLog -Filter @('and', @('authenticationType', 'eq', 'NONE')) -Order 'activityDate' Filter log results and order them .EXAMPLE Read-VaasLog -Filter @('and', @('authenticationType', 'eq', 'NONE')) -Order @{'activityDate'='desc'} Filter log results and order them descending .OUTPUTS Hashtable #> function New-VaasSearchQuery { [System.Diagnostics.CodeAnalysis.SuppressMessage('PSUseShouldProcessForStateChangingFunctions', '', Justification = 'No state is actually changing')] [CmdletBinding(SupportsPaging)] [OutputType([Hashtable])] param( [parameter()] [System.Collections.ArrayList] $Filter, [parameter()] [psobject[]] $Order ) begin { $operators = 'EQ', 'FIND', 'GT', 'GTE', 'IN', 'LT', 'LTE', 'MATCH' $query = @{ 'expression' = @{} 'ordering' = @{} 'paging' = @{} } if ($PSCmdlet.PagingParameters.First -ne [uint64]::MaxValue) { $query.paging.Add('pageSize', $PSCmdlet.PagingParameters.First) $query.paging.Add('pageNumber', 0) } function New-VaasExpression { [CmdletBinding()] param ( [parameter()] [psobject] $Filter ) $loopFilter = $Filter $operator = $null # first item may be the operator or a filter # if so, pull it off the list and process the rest if ($Filter[0].GetType().Name -eq 'String' -and $Filter[0] -in 'AND', 'OR') { $operator = $Filter[0].ToUpper() $loopFilter = $Filter | Select-Object -Skip 1 $loopFilter = @(, $loopFilter) } $operands = $loopFilter | ForEach-Object { $thisItem = $_ if ( $thisItem.count -eq 3 -and -not ($thisItem | ForEach-Object { if ($_.GetType().Name -eq 'Object[]') { 'array' } })) { $newOperand = @{ 'field' = $thisItem[0] 'operator' = $thisItem[1].ToUpper() } # handle different value types # note the use of property 'values' for an array, eg. when the operator is find, in, match switch ($thisItem[2].GetType().Name) { 'DateTime' { $newOperand.Add('value', ($thisItem[2] | ConvertTo-UtcIso8601)) } 'String' { $newOperand.Add('value', $thisItem[2]) } Default { # we have a list $newOperand.Add('values', $thisItem[2]) } } $newOperand } else { New-VaasExpression -Filter $thisItem } } if ( $operator ) { @{ 'operator' = $operator 'operands' = @($operands) } } else { $operands } } } process { if ( $Filter ) { $thisFilter = @(, $Filter) $query.expression = New-VaasExpression -Filter $thisFilter } if ( $Order ) { $query.ordering.Add('orders', @()) @($Order) | ForEach-Object { $thisOrder = $_ switch ($thisOrder.GetType().Name) { 'String' { $query.ordering.orders += @{ 'field' = $thisOrder 'direction' = 'ASC' } } 'HashTable' { $thisOrder.GetEnumerator() | ForEach-Object { if ( $_.Value -notin 'asc', 'desc' ) { throw ('Invalid order direction, {0}. Provide either ''asc'' or ''desc''' -f $_.Value) } $query.ordering.orders += @{ 'field' = $_.Key 'direction' = $_.Value.ToUpper() } } } Default { throw 'Invalid format for Order' } } } } $query } } |