SubmitGreenRadiusApiCall.ps1
|
function SubmitGreenRadiusApiCall { <# .NOTES Version 2026.3.13.1640 .SYNOPSIS Submits an API call to GreenRADIUS on behalf of another function in this module. .DESCRIPTION Submits an API call to GreenRADIUS on behalf of another function in this module. .OUTPUTS Returns a hashtable which was converted from the JSON returned by the server. If -MultiServer was present, then instead a hashtable will be returned in which the Keys are the names of the servers specified, and the Values are themselves the hashtables containing the responses from the corresponding servers. .PARAMETER Servers The servers(s) to send the API call to. If left blank, then the contents of $global:GreenRadiusApiSession.HostName will be used. This is specified when calling Connect-GreenRadiusApiSession. If -MultiServer is not specified, and multiple servers are specified, then only the first server in the array will be used. .PARAMETER Uri The URI, after the hostname of the server, which to call. Remember the leading slash. Example: "/gras-api/v2/mgmt/temporary-tokens" .PARAMETER Method The HTTP method to use. Valid values are GET, HEAD, POST, PUT, DELETE, CONNECT, OPTIONS, TRACE, and PATCH. (Though the actual GreenRADIUS API only supports GET, POST, PUT, and DELETE, at least at the time of this writing.) .PARAMETER Body Hashtable to be converted to JSON and sent over to the API. In the event that the hashtable is empty (e.g. you're calling Get-GreenRadiusTokenAssignments or Get-GreenRadiusAuthenticationRecords without any search parameters present) then *SOME* API endpoints will require that a blank Body be passed. Others will require no Body at all. For the former, simply passing an empty hashtable to parameter will be good. For the latter, pass $null to this parameter. At the time of this writing, the only function that requires a $null -Body if not specifying search terms is Get-GreenRadiusBlockStatus. I do not know why GRS has programmed that particular API endpoint in this differing way. .PARAMETER MultiServer If present, the query can be sent to multiple servers. Otherwise, the request will only be sent to a single server .PARAMETER RawRequest Variable name, without the dollar sign, in which to store the raw request which was created and sent to the API, before it was converted to JSON. This does not need to be a pre-existing variable. Mostly used for debugging the other functions in this module. This uses the Global scope. .PARAMETER RawResponse Variable name, without the dollar sign, in which to store the raw response from the API, converted from JSON. This is essentially an identical copy of what is returned by this function, except this will be made available outside of the module. This does not need to be a pre-existing variable. Mostly used for debugging the other functions in this module. This uses the Global scope. #> [CmdletBinding(DefaultParameterSetName = 'Default')] param ( [Parameter(Mandatory=$true)] [string]$Uri, [string[]]$Servers, [Parameter(Mandatory=$true)] [ValidateSet("GET", "HEAD", "POST", "PUT", "DELETE", "CONNECT", "OPTIONS", "TRACE", "PATCH")] [string]$Method, [hashtable]$Body, [switch]$MultiServer, [string]$RawRequest, [string]$RawResponse ) if ($RawRequest) { Set-Variable -Name $RawRequest -Value $Body -Scope Global -Force } $apiParameters = @{ Method = $Method Credential = $global:GreenRadiusApiSession.Credential ContentType = "application/json" } if ($Body -ne $null) { $apiParameters.Body = ($Body | ConvertTo-Json -Depth 5) } if (-not $Servers) { $Servers = $global:GreenRadiusApiSession.HostName } $apiResponses = @{} :serverLoop for ($i = 0; $i -lt $Servers.Count; $i++) { $server = $Servers[$i] $apiParameters.Uri = "https://$($Servers[$i])$($Uri)" $statusCode = 0 $apiResult = Invoke-RestMethod @apiParameters -StatusCodeVariable "statusCode" -SkipHttpErrorCheck switch ($statusCode) { 0 { Write-Warning "Connection to $($Servers[$i]) failed!" } 401 { Write-Warning "Incorrect API username or password given for $($Servers[$i])!" } 404 { Write-Warning "URL at $($apiParameters.Uri) not found!" } 429 { Write-Warning "Too many requests! You are being rate limited by the API. Retrying in $($global:GreenRadiusApiSession.RateLimitPauseTime) seconds..." Start-Sleep -Seconds $($global:GreenRadiusApiSession.RateLimitPauseTime) $i-- continue } 200 { if ($apiResult.GetType().Name -eq "String") { #This only seems necessary for the /tokenassignment api (used in Get-GreenRadiusTokenAssignments) #and even then only when no search parameters are specified, but here we go anyway $apiResult = $apiResult | ConvertFrom-Json -AsHashTable } if ($MultiServer) { $apiResponses.$($Servers[$i]) = $apiResult continue serverLoop } else { $apiResponses = $apiResult break serverLoop } } default { Write-Error "Status code $statusCode returned by $apiParameters.Uri! Please report this to the Powershell module developer." } } } if ($RawResponse) { Set-Variable -Name $RawResponse -Value $apiResponses -Scope Global -Force } return $apiResponses } <# LICENSE Copyright (c) 2026 Derek Howard and the City of Eureka, California Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, and/or distribute copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software, and the original author shall be credited as having created the original work. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #> |