Public/Invoke-GraphRequest.ps1
<# .NOTES =========================================================================== Created with: SAPIEN Technologies, Inc., PowerShell Studio 2017 v5.4.135 Created on: 2/13/2017 6:14 AM Edited on: 2/16/2017 Created by: Mark Kraus Organization: Mitel Filename: Invoke-GraphRequest.ps1 =========================================================================== .DESCRIPTION Invoke-GraphRequest Function #> <# .SYNOPSIS Submits an access reqest to the Graph API .DESCRIPTION This is esentially an Invoke-ebRequest wrapper that handles the Access Token lifecycle and Authorization header. This requires a valid Access Token in the form of a MSGraphAPI.Oauth.AccessToken and returns a MSGraphAPI.RequestResult Object .PARAMETER AccessToken MSGraphAPI.Oauth.AccessToken object obtained from Get-GraphOauthAccessToken. .PARAMETER Uri Specifies the Uniform Resource Identifier (URI) of the Internet resource to which the web request is sent. Enter a URI. This parameter supports HTTP, HTTPS, FTP, and FILE values. .PARAMETER Method Specifies the method used for the web request. The acceptable values for this parameter are: - Default - Delete - Get - Head - Merge - Options - Patch - Post - Put - Trace .PARAMETER Body Specifies the body of the request. The body is the content of the request that follows the headers. The Body parameter can be used to specify a list of query parameters or specify the content of the response. When the input is a GET request and the body is an IDictionary (typically, a hash table), the body is added to the URI as query parameters. For other GET requests, the body is set as the value of the request body in the standard name=value format. When the body is a form, or it is the output of an Invoke-GraphRequest call, Windows PowerShell sets the request content to the form fields. .PARAMETER Headers Specifies the headers of the web request. Enter a hash table or dictionary. Any Authirzation header supplied here will be overwritten by what is provided in the Access Token. To set UserAgent headers, use the UserAgent parameter. You cannot use this parameter to specify UserAgent or cookie headers. .PARAMETER TimeoutSec Specifies how long the request can be pending before it times out. Enter a value in seconds. The default value, 0, specifies an indefinite time-out. A Domain Name System (DNS) query can take up to 15 seconds to return or time out. If your request contains a host name that requires resolution, and you set TimeoutSec to a value greater than zero, but less than 15 seconds, it can take 15 seconds or more before a WebException is thrown, and your request times out. .PARAMETER ContentType Specifies the content type of the web request. The default value is 'application/json' .EXAMPLE PS C:\> Invoke-GraphRequest -AccessToken $value1 -Uri 'Value2' -Method $value3 .OUTPUTS MSGraphAPI.RequestResult #> function Invoke-GraphRequest { [CmdletBinding(ConfirmImpact = 'Low', SupportsShouldProcess = $true)] [OutputType('MSGraphAPI.RequestResult')] param ( [Parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)] [ValidateNotNullOrEmpty()] [PSTypeName('MSGraphAPI.Oauth.AccessToken')]$AccessToken, [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [System.Uri]$Uri, [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [Microsoft.PowerShell.Commands.WebRequestMethod]$Method = 'Default', [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)] [Object]$Body, [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)] [ValidateNotNullOrEmpty()] [System.Collections.IDictionary]$Headers, [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)] [ValidateRange(0,2147483647)] [System.Int32]$TimeoutSec, [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)] [System.String]$ContentType = 'application/json' ) Process { Try { Write-Verbose "Performing token refresh" $AccessToken | Update-GraphOauthAccessToken -ErrorAction Stop } Catch { $ErrorMessage = "Unable to refresh Access Token '{0}': {1}" -f $AccessToken.GUID, $_.Exception.Message Write-Error $ErrorMessage return } if (-not $pscmdlet.ShouldProcess("$Uri")) { Return } Write-Verbose "Set base parameters" $Params = @{ ContentType = $ContentType Uri = $Uri WebSession = $AccessToken.Session Method = $Method ErrorAction = 'Stop' } if ($Body) { Write-Verbose "Setting Body Parameter" $Params['Body'] = $Body } if ($TimeoutSec) { Write-Verbose "Setting TimeoutSec Parameter" $Params['TimeoutSec'] = $TimeoutSec } Write-Verbose "Setting Headers Parameter" $Params['Headers'] = @{ } if ($Headers) { Write-Verbose "Setting user supplied headers" $Params['Headers'] = $Headers } Write-Verbose "Setting Authorization header" $Params['Headers']['Authorization'] = 'Bearer {0}' -f $AccessToken.GetAccessToken() $RequestedDate = Get-Date try { $Result = Invoke-WebRequest @Params $ReceivedDate = Get-Date } catch { $response = $_.Exception.Response $Stream = $response.GetResponseStream() $Stream.Position = 0 $StreamReader = New-Object System.IO.StreamReader $Stream $ResponseBody = $StreamReader.ReadToEnd() $ErrorMessage = "Unable to query Uri '{0}': {1}: {2}" -f $Uri, $_.Exception.Message, $ResponseBody Set-Variable -Scope global -Name _invokeGraphRequestException -Value $_ Write-Error -message $ErrorMessage -Exception $_.Exception return } Write-Verbose "Truncating Authorization header" try { $Params['Headers']['Authorization'] = '{0}...{1}<truncated>' -f $Params.Headers.Authorization.Substring(0, 25), $Params.Headers.Authorization.Substring(($Params.Headers.Authorization.Length - 11), 10) } catch { Write-Verbose "No Authorization header to truncate" } switch ($Result.Headers.'Content-Type') { { $_ -match 'application/json' } { Write-Verbose "Converting result from JSON to PSObject" $ConentObject = $Result.Content | ConvertFrom-Json -ErrorAction SilentlyContinue break } { $_ -match 'application/xml' } { Write-Verbose "Converting result from XML to PSObject" [xml]$ConentObject = $Result.Content break } default { Write-Verbose "Unhandled Content-Type. ContentObject will be raw." $ConentObject = $Result.Content } } Write-Verbose "Setting LastRequestDate on Access Token" $AccessToken.LastRequestDate = $RequestedDate [pscustomobject]@{ PSTypeName = 'MSGraphAPI.RequestResult' Result = $Result Uri = $Uri Headers = $Params.Headers InvokeWebRequestParameters = $Params ContentType = $ContentType TimeoutSec = $TimeoutSec Body = $Body RequestedDate = $RequestedDate RecievedDate = $ReceivedDate AccessToken = $AccessToken ContentObject = $ConentObject } } } |