Powershell/Private/JumpCloudApi/Invoke-SystemAPI.ps1
|
function Invoke-SystemAPI { param ( [Parameter(Mandatory = $true)] [string]$jcApiKey, [Parameter(Mandatory = $false)] [string]$jcOrgID, [Parameter(Mandatory = $true)] [string]$systemId, [Parameter(Mandatory = $false)] [object]$Body, [Parameter(Mandatory = $false)] [string]$method = "PUT" ) $uri = "$($global:JCUrl)/api/systems/$systemId" $Headers = @{ 'Accept' = 'application/json'; 'Content-Type' = 'application/json'; 'x-api-key' = $jcApiKey; } if ($jcOrgID) { $Headers['x-org-id'] = $jcOrgID; } # region Attribute Mapping # Check if this is a PUT request containing 'attributes' if ($method -eq 'PUT' -and $Body -and $Body.ContainsKey('attributes')) { # Fetch current system to get existing attributes try { $currentSystem = Invoke-RestMethod -Uri $uri -Method 'GET' -Headers $Headers $currentAttributes = $currentSystem.attributes } catch { Write-ToLog "Attribute Merge Failed: Could not retrieve current system state. $($_.Exception.Message)" -Level 'Error' return } $incomingAttributes = $Body.attributes if ($incomingAttributes -is [string]) { # Handle case where user passed ConvertTo-Json string try { $incomingAttributes = $incomingAttributes | ConvertFrom-Json } catch { Write-ToLog "Failed to parse attributes JSON string." -Level 'Error' } } # Start with existing attributes (or empty array if none exist) $mergedAttributes = @() if ($null -ne $currentAttributes) { foreach ($attr in $currentAttributes) { $mergedAttributes += $attr } } # Merge $properties = if ($incomingAttributes -is [hashtable]) { $incomingAttributes.Keys } else { $incomingAttributes.PSObject.Properties.Name } foreach ($key in $properties) { $newValue = if ($incomingAttributes -is [hashtable]) { $incomingAttributes[$key] } else { $incomingAttributes.$key } $existingAttr = $mergedAttributes | Where-Object { $_.name -eq $key } if ($null -eq $newValue) { # Value is null, Remove the attribute if ($existingAttr) { $mergedAttributes = @($mergedAttributes | Where-Object { $_.name -ne $key }) } } elseif ($existingAttr) { # Exists -> Update value $existingAttr.value = [string]$newValue } else { # New -> Add new object $newAttr = @{ name = $key value = [string]$newValue } $mergedAttributes += $newAttr } } # Update the Body with the newly merged array $Body['attributes'] = $mergedAttributes } # endRegion Attribute Mapping $maxRetries = 3 $retryCount = 0 do { try { if ($Body) { $bodyContent = $Body | ConvertTo-Json -Depth 10 -Compress } else { $bodyContent = $null } $response = Invoke-RestMethod -Uri $uri -Method $method -Headers $Headers -Body $bodyContent $retry = $false } catch { if ($_.Exception.Message -like "*The remote name could not be resolved*") { $retryCount++ Start-Sleep -Seconds 2 $retry = $true } else { $ErrorMessage = $_.Exception.Message Write-ToLog "Failed to update system: $($ErrorMessage)" -Level Warning -Step "Invoke-SystemAPI" # exit the loop $retry = $false } } } while ($retry -and $retryCount -lt $maxRetries) if ($retryCount -eq $maxRetries) { Write-ToLog "Failed to resolve 'console.jumpcloud.com' after $maxRetries attempts." -Level Warning -Step "Invoke-SystemAPI" } if ($response) { return $response } } |