private/utility/Invoke-ConfluenceRestMethod.ps1
#NOTE: Multipart requests are only supported in PowerShell 6+ function Invoke-ConfluenceRestMethod { [CmdletBinding(DefaultParameterSetName="NoBody-HashQuery")] param ( # The Confluence Connection to use, if a session is not active. The hashtable must have AuthHeader and HostName properties. [Parameter(Mandatory,Position=0)] [AllowNull()] [hashtable] $ConfluenceConnection, # The URI path of function to invoke (do not include host name) [Parameter(Mandatory,Position=1)] [string] $FunctionPath, # The HTTP method to use for the request [Parameter(Mandatory,Position=2)] [ValidateSet("GET","POST","PUT","PATCH","DELETE")] [string] $HttpMethod, # Addtional headers to be added to the request (Auth and Content Type are included automatically) [Parameter(Position=3)] [hashtable] $Headers=@{}, # Used the same as the $Body param, but these parameters will be put into the query string [Parameter(ParameterSetName="NoBody-HashQuery",Position=4)] [Parameter(ParameterSetName="Multipart",Position=4)] [Parameter(ParameterSetName="File",Position=4)] [Parameter(Mandatory,ParameterSetName="JsonBody-HashQuery",Position=4)] [Parameter(Mandatory,ParameterSetName="SimpleBody-HashQuery",Position=4)] [ValidateNotNull()] [hashtable] $Query, # Query string key value pairs passed as an array of objects created by Format-QueryKvp [Parameter(Mandatory,ParameterSetName="NoBody-ArrayQuery",Position=4)] [Parameter(Mandatory,ParameterSetName="JsonBody-ArrayQuery",Position=4)] [Parameter(Mandatory,ParameterSetName="SimpleBody-ArrayQuery",Position=4)] [ValidateNotNull()] [object[]] $QueryKvp, # The body of the request. Will be serialized to json. [Parameter(Mandatory,ParameterSetName="JsonBody",Position=4)] [Parameter(Mandatory,ParameterSetName="JsonBody-HashQuery",Position=5)] [Parameter(Mandatory,ParameterSetName="JsonBody-ArrayQuery",Position=5)] [ValidateNotNull()] [hashtable] $Body, # Allows passing a raw string for the body of the request [Parameter(Mandatory,ParameterSetName="SimpleBody",Position=4)] [Parameter(Mandatory,ParameterSetName="SimpleBody-HashQuery",Position=5)] [Parameter(Mandatory,ParameterSetName="SimpleBody-ArrayQuery",Position=5)] [AllowEmptyString()] [string] $LiteralBody, # The Form values for a multipart request [Parameter(Mandatory,ParameterSetName="Multipart",Position=5)] [ValidateNotNull()] [hashtable] $Form, # The file object, when POST-ing or PUT-ing a file [Parameter(Mandatory,ParameterSetName="File",Position=5)] [object] $File ) process { #validate $ConfluenceConnection if($null -eq $ConfluenceConnection) { $ConfluenceConnection = $Global:PowerConfluence.Session } if($null -eq $ConfluenceConnection) {throw "Missing/Malformed ConfluenceConnection: No ConfluenceConnection object provided, and no ConfluenceSession open."} if(!($ConfluenceConnection.ContainsKey("AuthHeader") -and $ConfluenceConnection.ContainsKey("HostName"))) {throw "Missing/Malformed ConfluenceConnection: The provided object is missing one of the required properties (AuthHeader and HostName)."} #validate method / body combination if ((@("GET","DELETE") -contains $HttpMethod) -and !($PSCmdlet.ParameterSetName -match "NoBody")) { throw "Invalid HttpMethod / Parameter combination: Cannot use HttpMethod '$HttpMethod' with -Body, -LiteralBody, or -Form" } #compile headers object $sendHeaders = @{} $sendHeaders += $ConfluenceConnection.AuthHeader $sendHeaders += $Headers #set the default content type $contentType = 'application/json' #define uri $hostname = if($ConfluenceConnection.HostName.EndsWith("/")) { $ConfluenceConnection.HostName.Substring(0, ($ConfluenceConnection.HostName.Length - 1))} else {$ConfluenceConnection.HostName} $function = If($FunctionPath.StartsWith("/")) {$FunctionPath.Substring(1)} else {$FunctionPath} $uri = "$hostname/$function" if($PSBoundParameters.ContainsKey("Query") -and ($Query.Keys.Count -gt 0)){ $uri += '?' + (Format-HashtableToQueryString $Query) } elseif ($PSBoundParameters.ContainsKey("QueryKvp") -and ($QueryKvp.Count -gt 0)) { $uri += '?' + (Format-KvpArrayToQueryString $QueryKvp) } #select correct invocation depending on parameters provided switch ($PSCmdlet.ParameterSetName) { {($_ -match "NoBody") -or (($_ -match "JsonBody") -and ($Body.Count -eq 0))} { Invoke-RestMethod -Uri $uri -Method $HttpMethod -ContentType $contentType -Headers $sendHeaders } {$_ -match "JsonBody"} { $bodyDepth = Find-HashtableDepth $Body $bodyJson = ConvertTo-Json $Body -Compress -Depth $bodyDepth Invoke-RestMethod -Uri $uri -Method $HttpMethod -ContentType $contentType -Headers $sendHeaders -Body $bodyJson } {$_ -match "SimpleBody"} { Invoke-RestMethod -Uri $uri -Method $HttpMethod -ContentType $contentType -Headers $sendHeaders -Body $LiteralBody } {$_ -match "Multipart"} { $sendHeaders.Add("X-Atlassian-Token","no-check") Invoke-RestMethod -Uri $uri -Method $HttpMethod -Headers $sendHeaders -Form $Form } {$_ -match "File"} { $sendHeaders.Add("X-Atlassian-Token","no-check") Invoke-RestMethod -Uri $uri -Method $HttpMethod -Headers $sendHeaders -InFile $File } Default { throw "Invalid Parameter Set: Unknown parameter set '$_' in Invoke-ConfluenceRestMethod" } } } } |