#################### Core query wrappers - BEGIN #################### #region Function Invoke-CoreMethodWrapper { <# .SYNOPSIS Wrapper function around method queries in CTKAPI .DESCRIPTION Wrapper function around method queries in Core. Allows the use of any method in the CTKAPI You would not use this function directly, instead you should use a function that calls this function That way you can ensure proper validation of the method arguments in the function above this one Example of methods for Computer are here: https://ws.core.rackspace.com/ctkapi/browse/Computer/Computer Check the method section This function serves as a wrapper around Invoke-CoreQuery to make creating the method functions a lot easier Avoid calling it directly .PARAMETER LoadArgument Mandatory This is the main load argument for a method, this will be in the documentation and is normally a computer, ticket or other attribute ID .PARAMETER KeywordArgs Mandatory This is a hashtable of the paramaters required for the method, as per the CTKAPI documentation For example, the addComputer method on the Ticket class has one param, computer, so this would look something like: @{computer=560559} .PARAMETER Method Mandatory This is the method name. This is case sensitive and should be in camelCase! .PARAMETER Class Mandatory The main class your method is under. If the subclass is the same as the class, for example Computer.Computer you only need to supply the Class. This is case sensitive and should be in PascalCase! If you have a sub class that is different, like "Ticket.Queue", use the Subclass param .PARAMETER Subclass The subclass your method is under, for example "Queue" in "Ticket.Queue" This is case sensitive and should be in PascalCase! .EXAMPLE Set ticket status to confirm solved $Result = Invoke-CoreMethodWrapper -LoadArgument $TicketNumber -KeywordArgs @{status_name = "Confirm Solved"} -Method "setStatusByName" -Class Ticket .EXAMPLE Get subcategories for a ticket queue $Result = Invoke-CoreMethodWrapper -LoadArgument $QueueId -KeywordArgs @{} -Method "getSubcategories" -Class Ticket -Subclass "Queue" .OUTPUTS Core object .NOTES Written by Martin Howlett #> Param ( [Parameter(Mandatory=$true)] [ValidateNotNullOrEmpty()] [String]$LoadArgument, [Parameter(Mandatory=$true)] [Hashtable]$KeywordArgs, [Parameter(Mandatory=$true)] [ValidateNotNullOrEmpty()] [String]$Method, [Parameter(Mandatory=$true)] [Validateset(“Ticket”,"Computer","Account")] [ValidateNotNullOrEmpty()] [String]$Class, [Parameter()] [ValidatePattern("^[A-Z]{1}")] [ValidateNotNullOrEmpty()] [String]$Subclass = $Class ) Write-Verbose "Start of $($MyInvocation.MyCommand)" #Make sure only first letter is uppercase on class and subclass $Class = $Class.substring(0,1).toupper()+$Class.substring(1) $SubClass = $SubClass.substring(0,1).toupper()+$SubClass.substring(1) #Make sure the method is in camelCase. I can set the first letter, the rest will had to hope? $Method = $Method.substring(0,1).tolower()+$Method.substring(1) [Hashtable]$JsonHashtable = @{ "class" = "$Class.$Subclass"; "method" = $Method "load_arg" = $LoadArgument "keyword_args" = $KeywordArgs "args" = @() #required by core even though blank } [Hashtable]$InvokeCoreParams = @{ JsonHashtable = $JsonHashtable } $AllResult = Invoke-CoreQuery @InvokeCoreParams Write-Verbose "End of $($MyInvocation.MyCommand)" Return $AllResult } Function Invoke-CoreSetAttributeWrapper { <# .SYNOPSIS !!! IN PROGRESS !!! See Invoke-CoreWhereWrapper -SetAttribute param. This is being kept incase we have a requirement for it later down the line. Wrapper function around set attribute queries in Core .DESCRIPTION Wrapper function around set attribute queries in Core .PARAMETER LoadArgument Mandatory .PARAMETER SetAttributes Mandatory .PARAMETER Class Mandatory .EXAMPLE .OUTPUTS .NOTES Written by Martin Howlett #> Param ( [Parameter(Mandatory=$true)] [ValidateNotNullOrEmpty()] [String]$LoadArgument, [Parameter(Mandatory=$true)] [ValidateNotNullOrEmpty()] [Hashtable]$SetAttributes, [Parameter(Mandatory=$true)] [Validateset(“Ticket”,"Computer")] [ValidateNotNullOrEmpty()] [String]$Class ) Write-Verbose "Start of $($MyInvocation.MyCommand)" #Make sure only first letter is uppercase on class and subclass $Class = $Class.substring(0,1).toupper()+$Class.substring(1) $SubClass = $SubClass.substring(0,1).toupper()+$SubClass.substring(1) [Hashtable]$JsonHashtable = @{ "class" = "$Class.$Class"; "load_arg" = $LoadArgument "set_attribute" = $SetAttributes } [Hashtable]$InvokeCoreParams = @{ JsonHashtable = $JsonHashtable } $AllResult = Invoke-CoreQuery @InvokeCoreParams <# Parse output to something nice #> Write-Verbose "End of $($MyInvocation.MyCommand)" Return $AllResult } Function Invoke-CoreWhereWrapper { <# .SYNOPSIS Wrapper function around where query statements in Core .DESCRIPTION Internal function Wrapper to handle sending where statements to Core Will take input as Powershell objects and collate them into a JsonObject ready to hand off to Invoke-CoreQuery Will also sort subattribute output by expanding it into a nice pretty object .PARAMETER SearchTerms Mandatory Hash table of search terms that will be converted to array list using Get-CoreQueryArrayList Hashtable is created by the specific function for the class you are searching for like Find-CoreTicket or Find-CoreComputer Example of hashtable: $SearchTerms = @{ "AssigneeSsos" = [Array]("current_assignee_sso","in", [Array]("mart6141")) "CreatedAfter" = [Array]("created","<","$(((Get-date).AddDays(-7)).ToString("yyyy-MM-dd HH:mm:ss"))") } The key is just a firendly name, the value is an array of values in Core query format. In this format: [Array]("attribute","operator","search criteria") .PARAMETER Attributes Mandatory Attributes to return in the query Should be a hashtable of friendly name as key and the actual attribute as the value Get with Get-CoreAttributes See their help for more information (example Get-CoreTicketAttributes) .PARAMETER Class Mandatory The class in Core to query For Where statements this is limited to the classes that support it. Look for a Where in the Core CTKCPI help: https://ws.core.rackspace.com/ctkapi/browse/ .PARAMETER QueryLimit The number of results to return before offsetting and breaking up the query output Default 100 .PARAMETER $SetAttribute Allow us to set attributes by passing in attribute or query related to attribute https://ws.core.rackspace.com/ctkapi/doc/query/#set_attribute .EXAMPLE Get all tickets assigned to mart6141 created in the last 7 days [Hashtable]$WrapperParams = @{ [Hashtable]$SearchTerms = @{ "AssigneeSsos" = [Array]("current_assignee_sso","in", [Array]("mart6141")) "CreatedAfter" = [Array]("created","<","$(((Get-date).AddDays(-7)).ToString("yyyy-MM-dd HH:mm:ss"))") } Attributes = Get-CoreTicketAttributes Class = "Ticket" QueryLimit = 50 } $result = Invoke-CoreWhereWrapper @WrapperParams $result.result | ft .EXAMPLE Setting ticket difficult on 2 tickets using SetAttribute parameter $SetAttribute = @{"difficulty"=2} $SearchTerms = @{"Tickets" = @( "number", "in", @("170623-02886","170726-03173") ) "Status" = @( "status_type", "in", @("8") ) } Invoke-CoreWhereWrapper -Class Ticket -SearchTerms $SearchTerms -SetAttribute $SetAttribute .OUTPUTS Result object from Core API .NOTES Written by Martin Howlett / Mark Wichall #> Param ( [Parameter(Mandatory=$true)] [ValidateNotNullOrEmpty()] [Hashtable]$SearchTerms, [Parameter()] [ValidateNotNullOrEmpty()] [Hashtable]$Attributes, [Parameter(Mandatory=$true)] [Validateset(“Ticket”,"Computer","Contact", "Account")] [String]$Class, [Parameter()] [ValidatePattern("^[A-Z]{1}")] [String]$Subclass = $Class, [ValidateRange(1,249)] [Parameter()] [int]$QueryLimit = 100, [Parameter()] [ValidateNotNullOrEmpty()] [Hashtable]$CustomAttributes, [Parameter()] [ValidateNotNullOrEmpty()] [Hashtable]$SetAttribute ) Write-Verbose "Start of $($MyInvocation.MyCommand)" #Make sure only first letter is uppercase on class $Class = $Class.substring(0,1).toupper()+$Class.substring(1).tolower() #this converts our hash table of search terms that the calling function would of created #and converts it to an arraylist, so it will be turned into proper Core JSON later $SearchTermsArray = Get-CoreQueryArrayList -Values $SearchTerms #Add any custom attributes if($CustomAttributes) { #Check for duplicate foreach ($Custom in $CustomAttributes.GetEnumerator()) { #if its not a duplicate, add it to our ComputerAttributes if ($Attributes.Values -notcontains $($Custom.Value)) { $Attributes.Add($Custom.Name,$Custom.Value) Write-Verbose "Custom param added - $($Custom.Name): $($Custom.Value)" } else { Write-Error "Duplicate custom attribute detected, not added - $($Custom.Name): $($Custom.Value)" } } } [Hashtable]$JsonHashtable = @{ "class" = "$Class.$SubClass"; "attributes" = $Attributes "load_arg" = @{ "class" = "$Class.$SubClass`Where" "values" = $SearchTermsArray "offset" = 0 "limit" = $QueryLimit } } #For using set_attribute we need to remove attributes parameter and add set_attribute If ($SetAttribute) { $JsonHashtable.Remove("attributes") $JsonHashtable.Add("set_attribute",$SetAttribute) } [Hashtable]$InvokeCoreParams = @{ JsonHashtable = $JsonHashtable QueryLimit = $QueryLimit } #run the actual query $AllResult = Invoke-CoreQuery @InvokeCoreParams #Don't run convert on a blank object e.g. core retrune no results If (($AllResult | Measure-Object).count -gt 0) { #Code to expand out sub attributes (Computers, ticket updates, skus) $AllResultExpanded = Convertfrom-Subattributes -AllResult $AllResult } Write-Verbose "End of $($MyInvocation.MyCommand)" #Return the result Return $AllResultExpanded } Function Invoke-CoreAttributeWrapper { <# .SYNOPSIS Wrapper function around attribute queries in Core .DESCRIPTION Internal function Wrapper to handle sending attribute queries to Core Generally avoid this function, use the WHERE wrapper as its far faster and more powerful However if you dont have any where methods on a class you can use this Will take input as Powershell objects and collate them into a JsonObject ready to hand off to Invoke-CoreQuery .PARAMETER Attributes Mandatory Attributes to return in the query Should be a hashtable of friendly name as key and the actual attribute as the value Get with Get-CoreAttributes See their help for more information (example Get-CoreTicketAttributes) .PARAMETER Class Mandatory The class in Core to query For Where statements this is limited to the classes that support it. Look for a Where in the Core CTKCPI help: https://ws.core.rackspace.com/ctkapi/browse/ .PARAMETER LoadArgument Mandatory This is the main load argument for an attribute, this will be in the documentation and is normally a computer, ticket or other attribute ID .PARAMETER LoadMethod Optional For more advanced core queries you can return a List .PARAMETER Subclass The subclass your method is under, for example "Queue" in "Ticket.Queue" This is case sensitive and should be in PascalCase! .EXAMPLE Get core account ID [Hashtable]$WrapperParams = @{ LoadArgument = "1103359" attributes = @{ "AccountId" = "id" } Class = "Account" } Invoke-CoreAttributeWrapper @WrapperParams $result = Invoke-CoreAttributeWrapper @WrapperParams $result.result | ft .OUTPUTS Result object from Core API .NOTES Written by Martin Howlett / Mark Wichall #> Param ( [Parameter(Mandatory=$true)] [ValidateNotNullOrEmpty()] $LoadArgument, [Parameter(Mandatory=$false)] [Validateset(“loadList”)] [String]$LoadMethod, [Parameter(Mandatory=$true)] [ValidateNotNullOrEmpty()] [Hashtable]$Attributes, [Parameter(Mandatory=$true)] [ValidatePattern("^[A-Z]{1}")] [Validateset(“Ticket”,"Computer","Account","DevContainer")] [String]$Class, [Parameter()] [ValidatePattern("^[A-Z]{1}")] [String]$Subclass = $Class ) Write-Verbose "Start of $($MyInvocation.MyCommand)" #Make sure only first letter is uppercase on class and subclass $Class = $Class.substring(0,1).toupper()+$Class.substring(1) $SubClass = $SubClass.substring(0,1).toupper()+$SubClass.substring(1) [Hashtable]$JsonHashtable = @{ "class" = "$Class.$Subclass"; "load_arg" = $LoadArgument "attributes" = $Attributes } if($LoadMethod) { $JsonHashtable.Add("load_method",$LoadMethod) } [Hashtable]$InvokeCoreParams = @{ JsonHashtable = $JsonHashtable } $AllResult = Invoke-CoreQuery @InvokeCoreParams Write-Verbose "End of $($MyInvocation.MyCommand)" Return $AllResult } #endregion ##################### Core query wrappers - END #####################