functions/New-CwmApiRequest.ps1
function New-CwmApiRequest { <# .SYNOPSIS Performs a query against the Connectwise Manage API .DESCRIPTION This is a very generic function that performs GET, POST, PATCH, PUT, and DELETE requests to the ConnectWise Manage API. If pageSize is not specified in the endpoint parameter, this function will automatically pull the maximum page size (1000). Whatever the pageSize, the function will loop to pull any additional pages, returning all responses combined into a single response object. .PARAMETER endpoint The ConnectWise Manage API endpoint to hit. .PARAMETER query The query to append to the URL when making the REST call. The query should NOT be URL encoded. .PARAMETER apiMethod API method (get, post, patch, put, delete) .PARAMETER apiRequestBody API request body .OUTPUTS [System.Object] custom object containing API response .EXAMPLE $tickets = New-CwmApiRequest -endpoint "/service/tickets" -query "conditions=board/id=1 and status/id=505&fields=id,owner/id" -apiMethod "get" .EXAMPLE .NOTES #> [CmdletBinding()] param ( [parameter(Mandatory=$true, ParameterSetName='guided')] [validateNotNullorEmpty()] [string]$endpoint, [parameter(Mandatory=$false, ParameterSetName='guided')] [validateNotNullorEmpty()] [string]$query, [parameter(Mandatory=$true, ParameterSetName='direct')] [validateNotNullorEmpty()] [string]$uri, [parameter(Mandatory=$true)] [validateNotNullorEmpty()] [string]$apiMethod, [parameter(Mandatory=$false)] [validateNotNullorEmpty()] [string]$apiRequestBody ) $errorAction = $PSBoundParameters["ErrorAction"] if(-not $errorAction){ $errorAction = $ErrorActionPreference } if ( $endpoint ) { Write-Debug "Endpoint: $endpoint" #where a client name has & (e.g. RHW - River Health & Wellness) we need need to replace the & with %26 in order to use CW API, #but cannot replace all & with %26 because & has a function in REST API calls $escapedQuery = ( [uri]::EscapeUriString( $query ) ).replace( '%20&%20', '%20%26%20' ) $uri = "https://" + $Script:cwmApiUri + $endpoint + $escapedQuery #pull maximum records allowable unless query already specifies a count if ( $uri.ToLower().IndexOf( "pagesize" ) -eq -1 -and $apiRequestBody -ieq "get" ) { if ( $uri.IndexOf( "?" ) -eq -1 ) { $uri += "?pageSize=1000" } else { $uri += "&pageSize=1000" } } } Write-Debug "Uri: $uri" Write-Debug "apiMethod: $apiMethod" #set the parameters for the request $params = @{ Uri = $uri Method = $apiMethod ContentType = 'application/json' Headers = @{ 'Authorization' = $Script:cwmApiAuthString 'clientId' = $Script:cwmApiClientId 'Accept' = 'application/vnd.connectwise.com+json' 'version' = $Script:cwmApiVersionCode } } #if body was defined (patch or put), add to params if ( $apiRequestBody ) { Write-Debug "apiRequestBody: $apiRequestBody" $params.Add( 'Body' , $apiRequestBody ) } #make api request try { $response = ( Invoke-WebRequest @params -UseBasicParsing ) | Select-Object StatusCode,Content,Headers } catch { if ( $errorAction.ToString().ToLower() -ne "silentlycontinue") { Write-Error "API Request failed`n$PSItem" } throw } $content = $response.content | ConvertFrom-Json if ( ( $null -eq $response.Headers['Link'] ) -or ( $response.Headers['Link'].IndexOf( 'rel="next"' ) -eq -1 ) ) { return $content } else { #extract 'next' url from a string like #<https://api-na.myconnectwise.net/v4_6_release/apis/3.0/service/tickets/?pageSize=1000&page=2>; rel="next", <https://api-na.myconnectwise.net/v4_6_release/apis/3.0/service/tickets/?pageSize=1000&page=230>; rel="last" $linkInfo = $response.Headers['Link'] $linkInfo = $linkInfo.Replace('rel=','').Replace('<','').Replace('>','').Replace('"','').Replace(' ','') $linkInfo = $linkInfo.Split(',') foreach ( $link in $linkInfo ) { $info = $link.split(';') if ( $info[1] -eq 'next') { $nextUrl = $info[0] } } $params = @{ "uri" = $nextUrl "apiMethod" = $apiMethod } if ( $apiRequestBody ) { $params.Add( 'apiRequestBody' , $apiRequestBody ) } $restOfContent = New-CwmApiRequest @params return $content + $restOfContent } } |