Public/Build-LMFilter.ps1
<# .SYNOPSIS Builds a filter expression for Logic Monitor API queries. .DESCRIPTION The Build-LMFilter function creates a filter expression by interactively prompting for conditions and operators. It supports basic filtering for single fields and advanced filtering for property-based queries. Multiple conditions can be combined using AND/OR operators. .PARAMETER PassThru When specified, returns the filter expression as a string instead of displaying it in a panel. .EXAMPLE #Build a basic filter expression Build-LMFilter This example launches the interactive filter builder wizard. .EXAMPLE #Build a filter and return the expression Build-LMFilter -PassThru This example builds a filter and returns the expression as a string. .NOTES The filter expression is saved to the global $LMFilter variable. .INPUTS None. You cannot pipe objects to this command. .OUTPUTS [String] Returns a PowerShell filter expression when using -PassThru. #> function Build-LMFilter { [CmdletBinding()] param( [Switch]$PassThru ) # Helper function for getting user selection function Get-UserSelection { param( [Parameter(Mandatory=$true)] [string]$Prompt, [Parameter(Mandatory=$true)] [array]$Choices, [Parameter(Mandatory=$true)] [string]$ChoiceLabelProperty ) Write-Host "$Prompt" for ($i = 0; $i -lt $Choices.Count; $i++) { Write-Host (" " + ($i + 1) + ". " + $Choices[$i].($ChoiceLabelProperty)) } $choiceNumber = 0 do { $choiceInput = Read-Host "Enter selection number (1-$($Choices.Count))" if ([int]::TryParse($choiceInput, [ref]$choiceNumber) -and $choiceNumber -ge 1 -and $choiceNumber -le $Choices.Count) { # Valid input } else { Write-Host "Invalid input. Please enter a number between 1 and $($Choices.Count)." -ForegroundColor Red $choiceNumber = 0 # Reset to ensure loop continues } } while ($choiceNumber -eq 0) return $Choices[$choiceNumber - 1] } # Helper function for getting user confirmation function Get-UserConfirmation { param( [Parameter(Mandatory=$true)] [string]$Prompt, [string]$DefaultAnswer = "n", [string]$ConfirmSuccess = "Proceeding...", [string]$ConfirmFailure = "Stopping..." ) $answer = "" $validAnswers = @("y", "n") do { $choiceInput = Read-Host "$Prompt (y/n) [$DefaultAnswer]" if ([string]::IsNullOrEmpty($choiceInput)) { $choiceInput = $DefaultAnswer } if ($validAnswers -contains $choiceInput.ToLower()) { $answer = $choiceInput.ToLower() } else { Write-Host "Invalid input. Please enter 'y' or 'n'." -ForegroundColor Red } } while ([string]::IsNullOrEmpty($answer)) if ($answer -eq 'y') { Write-Host $ConfirmSuccess return $true } else { Write-Host $ConfirmFailure return $false } } $Caller = $null #Check if called by another function, will be used to determine available fields in the future $CallStack = Get-PSCallStack if ($CallStack.Count -gt 1) { $Caller = $CallStack[1].FunctionName } $conditions = @() $operators = @( @{ Name = "Equals"; Value = "-eq" }, @{ Name = "Not Equals"; Value = "-ne" }, @{ Name = "Greater Than"; Value = "-gt" }, @{ Name = "Less Than"; Value = "-lt" }, @{ Name = "Contains"; Value = "-contains" }, @{ Name = "Not Contains"; Value = "-notcontains" } ) $valueTypes = @( @{ Name = "Basic Filtering"; Value = "B" }, @{ Name = "Advanced Property Filtering"; Value = "A" } ) $logicalOperators = @( @{ Name = "AND"; Value = "-and" }, @{ Name = "OR"; Value = "-or" } ) $propertyTypes = @( @{ Name = "System Property"; Value = "systemProperties" }, @{ Name = "Auto Property"; Value = "autoProperties" }, @{ Name = "Inherited Property"; Value = "inheritedProperties" }, @{ Name = "Custom Property"; Value = "customProperties" } ) Write-Host "Welcome to the Logic Monitor API Filter Builder! Use this wizard to build a filter expression for the Get-LM* cmdlets." #Explain the different types of filters Write-Host "" Write-Host "There are two types of filters: Basic and Advanced:" Write-Host " - Basic filters are used to filter based on a single field and a value such as displayName." Write-Host " - Advanced filters are used to filter based on a property and a value that is within that property. Applies to auto, system, inherited and custom properties." Write-Host "" Write-Host "Note: You can combine basic/advanced filters within the same filter equation using the AND or OR logical operators." Write-Host "Note: Currently, only devices, device groups, and alerts support advanced property filtering." Write-Host "" while ($true) { # Get value type first $selectedValueType = Get-UserSelection ` -Prompt "Select filter type:" ` -Choices $valueTypes ` -ChoiceLabelProperty "Name" $keyChar = $selectedValueType.Value # Get property name based on filter type switch ($keyChar) { "B" { $property = Read-Host "Enter attribute name" # Get operator $selectedOperator = Get-UserSelection ` -Prompt "Select operator:" ` -Choices $operators ` -ChoiceLabelProperty "Name" $operator = $selectedOperator.Value $valueInput = Read-Host "Enter value" # Ensure string values are quoted for the filter $value = "`"$valueInput`"" } "A" { $selectedProperty = Get-UserSelection ` -Prompt "Select property type:" ` -Choices $propertyTypes ` -ChoiceLabelProperty "Name" $property = $selectedProperty.Value # Get operator $selectedOperator = Get-UserSelection ` -Prompt "Select operator:" ` -Choices $operators ` -ChoiceLabelProperty "Name" $operator = $selectedOperator.Value $jsonProperty = Read-Host "Enter property name" $jsonValue = Read-Host "Enter property value" # Convert to JSON string suitable for LM API. Needs double conversion for proper escaping in the final filter string. $jsonObject = [ordered]@{ name = $jsonProperty; value = $jsonValue } | ConvertTo-Json -Compress | ConvertTo-Json -Compress $value = $jsonObject } } $conditions += "$property $operator $value" # First ask if they want to continue $continue = Get-UserConfirmation ` -Prompt "Would you like to add another condition?" ` -DefaultAnswer "n" ` -ConfirmSuccess "Adding another condition..." ` -ConfirmFailure "Finishing filter equation..." if (-not $continue) { break } # If they want to continue, ask for the logical operator $selectedLogicalOperator = Get-UserSelection ` -Prompt "Select logical operator" ` -Choices $logicalOperators ` -ChoiceLabelProperty "Name" $conditions += $selectedLogicalOperator.Value } $filterEquation = $conditions -join ' ' Set-Variable -Name "LMFilter" -Value $filterEquation -Scope global If (!$PassThru) { Write-Host "--- LM API Filter Equation ---" Write-Host "'$filterEquation'" Write-Host "-----------------------------" Write-Host "Filter equation has been saved to the `$LMFilter variable." -ForegroundColor Green return # Return nothing visually when not using PassThru } Else { Write-Host "Filter equation has been saved to the `$LMFilter variable." -ForegroundColor Green return $filterEquation # Return the string when using PassThru } } |