Private/Invoke-vCAVAPIRequest.ps1
function Invoke-vCAVAPIRequest(){ <# .SYNOPSIS This cmdlet will send a REST API call to a vCloud Availability Service and return an object containing the headers and the JSON data payload to the caller. If JSON is not returned by the call the Raw Data is returned to the caller. .DESCRIPTION The cmdlet acts as a wrapper to construct well formed HTTP headers and payload for a REST API call to a vCloud Availability Cloud-to-Cloud for DR service using the Invoke-WebRequest native method. To set the default behavior of PowerCLI when no valid certificates are recognized, use the InvalidCertificateAction parameter of the Set-PowerCLIConfiguration cmdlet. For more information about invalid certificates, run 'Get-Help about_invalid_certificates'. To set the proxy usage behavior of PowerCLI (eg. to bypass a proxy or to use the System Proxy), use the ProxyPolicy parameter of the Set-PowerCLIConfiguration cmdlet. .PARAMETER URI The fully qualified URI of the vCloud Availability API endpoint. .PARAMETER Method The HTTP Method to send for the API call .PARAMETER APIVersion The API version to be used for the API call .PARAMETER Data JSON data to be sent as the HTTP Payload in the API call. .PARAMETER CheckConnection If true, the current session/connection for vCloud Availability service set in $global:DefaultvCAVServer before making the API call. .PARAMETER Headers A Hashtable containing additional headers that should be passed during the API call. Any default headers will be overwritten. .PARAMETER QueryParameters A Hashtable containing a list of query parameters or specify the content of the response for a GET Request. .EXAMPLE Invoke-vCAVAPIRequest -URI ($global:DefaultvCAVServer.ServiceURI + "config/is-configured") -Method "Get" -APIVersion 1 Performs a HTTP GET request against the connected server/config/is-configured using API Version 1 and returns the JSON response. .EXAMPLE Invoke-vCAVAPIRequest -URI ($global:DefaultvCAVServer.ServiceURI + "license"") -Method "Get" -APIVersion 2 Performs a HTTP GET request against the connected server licnecing namespace using API Version 2 and returns the JSON response. .EXAMPLE Invoke-vCAVAPIRequest -URI ($global:DefaultvCAVServer.ServiceURI + "license"") -Method "Get" -APIVersion 2 -QueryParameters $htParameters Performs a HTTP GET request against the connected server licnecing namespace using API Version 2 and passes the parameters in the Hashatable $htParemeters as Query paremeters and returns the JSON response. .EXAMPLE Invoke-vCAVAPIRequest -URI ($global:DefaultvCAVServer.ServiceURI + "config/root-password") -Data (ConvertTo-JSON $objRootPassword) -Method Post -APIVersion 1 Performs a HTTP Post to reset the root password using the API verson 1 and forcing a certificate check. .NOTES This cmdlet obeys the ProxyPolicy and InvalidCertificateAction parameters set in the VMWare PowerCLI Configuration. There is a limitation for PowershellCore that at the cmdlet can only be used with the "UseSystemProxy" policy on Windows netsh winhttp show proxy settings; this will be changed in future AUTHOR: Adrian Begg LASTEDIT: 2019-09-10 VERSION: 3.2 #> Param( [Parameter(Mandatory=$True)] [ValidateScript({[system.uri]::IsWellFormedUriString($_,[System.UriKind]::Absolute)})] [string] $URI, [Parameter(Mandatory=$True)] [ValidateSet("Get","Put","Post","Delete","Patch")] [string] $Method, [Parameter(Mandatory=$True)] [ValidateSet(1,2,3,4)] [int] $APIVersion, [Parameter(Mandatory=$False)] [ValidateNotNullorEmpty()] [string] $Data, [Parameter(Mandatory=$False)] [bool] $CheckConnection = $true, [Parameter(Mandatory=$False)] [Hashtable] $Headers, [Parameter(Mandatory=$False)] [Hashtable] $QueryParameters ) # Validate the environment is ready based on the input parameters if($CheckConnection){ if(!(Test-VCAVServiceEnvironment)){ Break } } # Construct the headers for the API call $APIHeaders = @{ 'Content-Type' = 'application/json' } # Add the API Version Header if($APIVersion -eq 1){ $APIHeaders.Add('Accept','application/vnd.vmware.h4-v1+json') } elseif($APIVersion -eq 2){ $APIHeaders.Add('Accept','application/vnd.vmware.h4-v2+json') } elseif($APIVersion -eq 3){ $APIHeaders.Add('Accept','application/vnd.vmware.h4-v3+json') } elseif($APIVersion -eq 4){ $APIHeaders.Add('Accept','application/vnd.vmware.h4-v4+json') } # Add an Operation Id for Tracking Transactions in logs $APIHeaders.Add('operationID',("Powershell__$(New-Guid)")) # If not null add the Access Token for the API call to the header if(!([string]::IsNullOrEmpty($global:DefaultvCAVServer.AccessToken))){ $APIHeaders.Add('X-VCAV-Auth',$global:DefaultvCAVServer.AccessToken) } # Check if any custom headers have been provided and if they have set them if($Headers.Count -ne 0){ foreach($Key in $Headers.Keys){ $APIHeaders.$Key = $Headers.$Key } } # Create a Hashtable with base paramters to use for splatting to Invoke-WebRequest $HashInvokeArguments = @{ Uri = $URI Method = $Method Headers = $APIHeaders } # Next check the PowerCLI Proxy policy to determine if what Proxy Policy should be used for the API call and set accordingly if((Get-PowerCLIConfiguration -Scope "User" | Select-Object ProxyPolicy).ProxyPolicy -eq "NoProxy") { $HashInvokeArguments.Add("NoProxy",$true) } elseif((Get-PowerCLIConfiguration -Scope "User" | Select-Object ProxyPolicy).ProxyPolicy -eq "UseSystemProxy") { # Check the PowerShell edition first if($Global:PSEdition -eq "Desktop"){ $Proxy = ([System.Net.WebRequest]::GetSystemWebProxy()).GetProxy($URI) $HashInvokeArguments.Add("Proxy",$Proxy.AbsoluteUri) $HashInvokeArguments.Add("ProxyUseDefaultCredentials",$true) } elseif($Global:PSEdition -eq "Core") { # For PowerShell Core you can not use the [System.Net.WebProxy]::GetDefaultProxy() or [System.Net.WebRequest]::GetSystemWebproxy() static method as its not supported # Really not happy with this implementation but temporary until can write a better handler or support is added for GetDefaultProxy static method $Proxy = Get-WinHttpProxy if($Proxy.'Winhttp proxy' -ne "Direct Access"){ [string] $ProxyString = "http://$($Proxy.'Winhttp proxy')" $HashInvokeArguments.Add("Proxy",$ProxyString) $HashInvokeArguments.Add("ProxyUseDefaultCredentials",$true) } } } # Check if the Certificate Check should be performed and add the argument if not if((Get-PowerCLIConfiguration -Scope "User" | Select-Object InvalidCertificateAction).InvalidCertificateAction -eq "Ignore") { $HashInvokeArguments.Add("SkipCertificateCheck",$true) } # Check first if the method is a GET, if it is check if the a set of QueryParameters has been provided and set as the body, else if anything else then Body should be set as the $Data if(($Method -eq "Get") -and ($PSBoundParameters.ContainsKey("QueryParameters"))){ $HashInvokeArguments.Add("Body", $QueryParameters) } elseif($PSBoundParameters.ContainsKey("Data")){ $HashInvokeArguments.Add("Body", $Data) } # Now try and make the API call try{ $Request = Invoke-WebRequest @HashInvokeArguments $objResponse = New-Object System.Management.Automation.PSObject $objResponse | Add-Member Note* Headers $Request.Headers if($null -ne $Request.Content){ try{ $objResponse | Add-Member Note* JSONData (ConvertFrom-JSON ([System.Text.Encoding]::UTF8.GetString($Request.Content))) } catch { # For non-JSON payloads $objResponse | Add-Member Note* RawData $Request.Content } } $objResponse } catch { if($_.Exception.Response.StatusCode -eq "Unauthorized"){ throw [System.UnauthorizedAccessException] "An Unauhorized Exception was thrown attempting to make the API call to $URI. Please check that you have the required permissions to execute this call and that you have a current connected session." } else { throw "An error occurred making an API call to $URI. Exception details: $($_.Exception)" } } } |