Private/New-HaloGETRequest.ps1
|
function New-HaloGETRequest { <# .SYNOPSIS Builds a request for the Halo API. .DESCRIPTION Wrapper function to build web requests for the Halo API. .EXAMPLE PS C:\> New-HaloGETRequest -Method "GET" -Resource "/api/Articles" Gets all Knowledgebase Articles .OUTPUTS Outputs an object containing the response from the web request. #> [CmdletBinding()] [OutputType([Object])] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '', Justification = 'Private function - no need to support.')] param ( # The HTTP request method. [Parameter( Mandatory = $True )] [String]$Method, # The resource to send the request to. [Parameter( Mandatory = $True )] [String]$Resource, # Returns the Raw result. Useful for file downloads [Switch]$RawResult, # A hashtable used to build the query string. [Hashtable]$QSCollection, # Disables auto pagination. [Switch]$AutoPaginateOff, # The key for the results object. [String]$ResourceType ) Invoke-HaloPreFlightCheck try { if (($null -ne $QSCollection) -and ($QSCollection.pageinate -eq 'true') -and (-not($AutoPaginateOff))) { Write-Verbose 'Automatically paginating.' $PageNum = $QSCollection.page_no $PageSize = $QSCollection.page_size } elseif ((-not $QSCollection.pageinate) -and ($QSCollection.page_size)) { $QSCollection.Remove('page_size') } if (-not $RawResult) { $RawResult = $False } if ($QSCollection) { Write-Debug ('Query string collection in New-HaloGETRequest contains: {0}' -f ($QSCollection | Out-String)) $QueryStringCollection = [system.web.httputility]::ParseQueryString([string]::Empty) Write-Verbose 'Building [HttpQSCollection] for New-HaloGETRequest' foreach ($Key in $QSCollection.Keys) { $QueryValue = $QSCollection[$Key] if ($QueryValue -is [array]) { foreach ($Entry in $QueryValue) { $QueryStringCollection.Add($Key, $Entry) } } else { $QueryStringCollection.Add($Key, $QueryValue) } } } else { Write-Debug 'Query string collection not present...' } Write-Verbose ('Page Size: {0}' -f $PageSize) $QSBuilder = [System.UriBuilder]::new() if ($AutoPaginateOff) { Write-Debug 'Automatic pagination is off.' $QSBuilder.Query = $QueryStringCollection.ToString() $Query = $QSBuilder.Query.ToString() $WebRequestParams = @{ Method = $Method Uri = ('{0}{1}{2}' -f $Script:HAPIConnectionInformation.URL, $Resource, $Query) } Write-Debug ('Building new HaloRequest with params: {0}' -f ($WebRequestParams | Out-String)) $Response = Invoke-HaloRequest -WebRequestParams $WebRequestParams -RawResult:$RawResult Write-Debug ('Halo request returned {0}' -f ($Response | Out-String)) if ((-not [string]::IsNullOrWhiteSpace($ResourceType)) -and ($Response.PSObject.Properties.name -match $ResourceType) -and ($Response.$ResourceType -is [Object])) { $Result = $Response.$ResourceType } else { $Result = $Response } } elseif ($PageNum) { # The Halo API can silently cap the number of records returned on a page below the # requested page_size (e.g. asking for page_size=1000 but only ever getting 100 back). # Basing the page count on the *requested* page size then under-counts how many pages # actually exist, so instead we capture the actual size of the first page returned and # use that consistently for every subsequent page-count calculation. Later pages - # including a short final page - don't change this, so the loop still stops at the # right point instead of assuming every page is as small as the last one. $EffectivePageSize = $null $Result = do { Write-Verbose ('Processing page {0}' -f $PageNum) $QueryStringCollection.Remove('page_no') $QueryStringCollection.Add('page_no', $PageNum) $QSBuilder.Query = $QueryStringCollection.ToString() $Query = $QSBuilder.Query.ToString() $WebRequestParams = @{ Method = $Method Uri = ('{0}{1}{2}' -f $Script:HAPIConnectionInformation.URL, $Resource, $Query) } Write-Debug ('Building new HaloRequest with params: {0}' -f ($WebRequestParams | Out-String)) $Response = Invoke-HaloRequest -WebRequestParams $WebRequestParams -RawResult:$RawResult Write-Debug ('Halo request returned {0}' -f ($Response | Out-String)) if ((-not [string]::IsNullOrWhiteSpace($ResourceType)) -and ($Response.PSObject.Properties.name -match $ResourceType) -and ($Response.$ResourceType -is [Object])) { $PageResults = $Response.$ResourceType } else { $PageResults = $Response } if (-not $EffectivePageSize) { $ActualCount = @($PageResults).Count $EffectivePageSize = if ($ActualCount -gt 0) { $ActualCount } else { $PageSize } } try { $NumPages = [Math]::Ceiling($Response.record_count / $EffectivePageSize) } catch { $NumPages = 1 } Write-Verbose ('Total number of pages to process: {0}' -f $NumPages) $PageNum++ $PageResults } while ($PageNum -le $NumPages) } Return $Result } catch [Microsoft.PowerShell.Commands.HttpResponseException] { throw $_ } catch { New-HaloError -ErrorRecord $_ } } |