Private/Get-TraverseFlexCommand.ps1
function Get-TraverseFlexCommand { <# .SYNOPSIS Generates Powershell Commands from the Traverse FlexAPI #> [CmdletBinding()] param () $HelpResult = invoke-traversecommand "help" $HelpResult | where {$PSItem -notmatch '^End with .quit*'} | foreach { #Initialize special matches variable just in case $Matches = $null #Parse out the various inital elements of the command #Initialize the hashtable so that PSCustomObject doesn't mess it up later $cmdParts = [ordered]@{ #Get the original command, used later for aliasing command = $PSItem -replace '^([a-z\.A-Z]*?) .*','$1' noun = $null verb = $null params = $null } if ($PSItem -match '^(?<noun>[a-zA-Z]*)\.?(?<verb>[a-zA-Z]*)\ (?<params>.*)') { #Save Matches result in case it changes due to processing or matching I do later $cmdMatches = $Matches #Used for TitleText conversion $TextInfo = (Get-Culture).TextInfo if ($cmdMatches['verb']) { #Capitalize first letter using TextInfo to meet Powershell Guidelines $cmdParts.verb = $TextInfo.ToTitleCase($cmdMatches['verb']).trim() } else { #Default to "Invoke" if no verb was found $cmdParts.verb = 'Invoke' } $cmdParts.noun = $TextInfo.ToTitleCase($cmdMatches['noun']).trim() #Process Parameter syntax for attributes $roughParams = @() $cmdMatches['params'] -split ', ' | foreach { $paramString = $PSItem.trim() $cmdParam = @{ name = $null mandatory = $null type = $null validate = $null parameterSet = $null argument = $null } #If the parameter is encapsulated in brackets, this means it is an optional parameter. Strip the brackets and add the appropriate tag. if ($paramString -match '^\[.*\]$') { $paramString = ($paramString -replace '^\[(.*)\]$','$1').trim() $cmdParam.mandatory = $false } else { $cmdParam.mandatory = $true } #If the parameter item has a | it's an "OR" parameter. #If its optional, just split it into two separate optional parameters #If it is mandatory, it should have its own parameter set #Unfortunately | is used inside of arguments so we can't just do a simple split, hence the fancy regex if ($paramstring -match '^(\".*?=.*?\") \| (\".*?=.*?\")$' ) { $result = $matches.remove(0) $i=1 #Create a new cmdParam object using the existing as a baseline #The keys need to be sorted so the parameters are processed in the correct order. #This is important for positional parameters $matches.keys | sort | foreach {$matches[$_]} | foreach { #DOESNT WORK WITH [ordered] $cmdParamNew = $cmdParam.Clone() $cmdParamNew.argument = $PSItem.trim() if ($cmdParamNew.mandatory) { $cmdParamNew.parameterSet = "Set$i" $i++ } $roughParams += $cmdParamNew } } else { $cmdParamNew = $cmdParam.Clone() $cmdParamNew.argument = $paramString.trim() $roughParams += $cmdParamNew } #TODO: If a parameter doesn't have brackets and is a constant value, it should be configured as a switch with its own parameter set } #Second Pass to clean up the parameter entries $finalParams = @() foreach ($roughParamItem in $roughParams) { #strip outer quotes if present $roughParamItem.argument = ($roughParamItem.argument -replace '^\"(.*)\"$','$1').trim() #Split the argument into its name and type definition $roughParamItem.name = ($roughParamItem.argument -split '=')[0].trim() $argTypeDef = ($roughParamItem.argument -split '=')[1].trim() #If the argument is not enclosed in brackets, it is a literal. For now just treat this as a string entry #TODO: ValidateSet for the literal to cut down on commands. if ($argTypeDef -notmatch '^\<.*\>$') { $roughParamItem.type = 'String' } else { #If it does have brackets, strip them and match for type $argTypeDef = $argTypeDef -replace '^\<(.*)\>$','$1' switch -regex ($argTypeDef) { #If it has multiple specific params, save them for defining for validationSet later #TODO: Define ValidationSet "true\|false" { $roughParamItem.type = 'Boolean' continue } "\|" { $roughParamItem.type = 'String' $roughParamItem.validateSet = $argTypeDef.split('|') continue } "^value$" {$roughParamItem.type = 'String'; continue} "^regexp$" {$roughParamItem.type = 'Regex'; continue} default {$roughParamItem.type = 'String'; continue} } } $finalParams += [PSCustomObject]$roughParamItem } $cmdParts.params = $finalParams } [PSCustomObject]$cmdParts } } |