/ Custom Windows PowerShell Function to Make SharePoint REST Service Calls
Last active May 1, 2020
Sends an HTTP or HTTPS request to a SharePoint Online REST-compliant web service using Windows PowerShell.
<# | |
.Synopsis | |
Clears the SharePoint Online credentials stored in the global variable. | |
.DESCRIPTION | |
Clears the SharePoint Online credentials stored in the global variable. | |
You can also manually clear the variable by explicitly setting | |
$global:spoCred = $null. | |
.EXAMPLE | |
Clear-SPORestCredentials | |
#> | |
function global:Clear-SPORestCredentials { | |
$global:spoCred = $null | |
} |
<# | |
.Synopsis | |
Sends an HTTP or HTTPS request to a SharePoint Online REST-compliant web service. | |
.DESCRIPTION | |
This function sends an HTTP or HTTPS request to a Representational State | |
Transfer (REST)-compliant ("RESTful") SharePoint Online web service. | |
When connecting, if Set-SPORestCredentials is not called then you will be | |
prompted for your credentials. Those credentials are stored in a global | |
variable $global:spoCred so that it will be available on subsequent calls. | |
Call Clear-SPORestCredentials to clear the variable. | |
.EXAMPLE | |
Invoke-SPORestMethod -Url "https://contoso.sharepoint.com/_api/web" | |
.EXAMPLE | |
Invoke-SPORestMethod -Url "https://contoso.sharepoint.com/_api/contextinfo" -Method "Post" | |
#> | |
function global:Invoke-SPORestMethod { | |
[CmdletBinding()] | |
[OutputType([int])] | |
Param ( | |
# The REST endpoint URL to call. | |
[Parameter(Mandatory = $true, ValueFromPipeline = $true, Position = 0)] | |
[ValidateNotNullOrEmpty()] | |
[System.Uri]$Url, | |
# Specifies the method used for the web request. The default value is "Get". | |
[Parameter(Mandatory = $false, Position = 1)] | |
[ValidateNotNullOrEmpty()] | |
[ValidateSet("Get", "Head", "Post", "Put", "Delete", "Trace", "Options", "Merge", "Patch")] | |
[string]$Method = "Get", | |
# Additional metadata that should be provided as part of the Body of the request. | |
[Parameter(Mandatory = $false, Position = 2)] | |
[ValidateNotNullOrEmpty()] | |
[object]$Metadata, | |
# The "X-RequestDigest" header to set. This is most commonly used to provide the form digest variable. Use "(Invoke-SPORestMethod -Url "https://contoso.sharepoint.com/_api/contextinfo" -Method "Post").GetContextWebInformation.FormDigestValue" to get the Form Digest value. | |
[Parameter(Mandatory = $false, Position = 3)] | |
[ValidateNotNullOrEmpty()] | |
[string]$RequestDigest, | |
# The "If-Match" header to set. Provide this to make sure you are not overwritting an item that has changed since you retrieved it. | |
[Parameter(Mandatory = $false, Position = 4)] | |
[ValidateNotNullOrEmpty()] | |
[string]$ETag, | |
# To work around the fact that many firewalls and other network intermediaries block HTTP verbs other than GET and POST, specify PUT, DELETE, or MERGE requests for -XHTTPMethod with a POST value for -Method. | |
[Parameter(Mandatory = $false, Position = 5)] | |
[ValidateNotNullOrEmpty()] | |
[ValidateSet("Get", "Head", "Post", "Put", "Delete", "Trace", "Options", "Merge", "Patch")] | |
[string]$XHTTPMethod, | |
[Parameter(Mandatory = $false, Position = 6)] | |
[ValidateNotNullOrEmpty()] | |
[ValidateSet("Verbose", "MinimalMetadata", "NoMetadata")] | |
[string]$JSONVerbosity = "Verbose", | |
# If the returned data is a binary data object such as a file from a SharePoint site specify the output file name to save the data to. | |
[Parameter(Mandatory = $false, Position = 7)] | |
[ValidateNotNullOrEmpty()] | |
[string]$OutFile | |
) | |
Begin { | |
if ((Get-Module Microsoft.Online.SharePoint.PowerShell -ListAvailable) -eq $null) { | |
throw "The Microsoft SharePoint Online PowerShell cmdlets have not been installed." | |
} | |
if ($global:spoCred -eq $null) { | |
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client.Runtime") | Out-Null | |
$cred = Get-Credential -Message "Enter your credentials for SharePoint Online:" | |
$global:spoCred = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($cred.UserName, $cred.Password) | |
} | |
} | |
Process { | |
$request = [System.Net.WebRequest]::Create($Url) | |
$request.Credentials = $global:spoCred | |
$odata = ";odata=$($JSONVerbosity.ToLower())" | |
$request.Accept = "application/json$odata" | |
$request.ContentType = "application/json$odata" | |
$request.Headers.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f") | |
$request.Method = $Method.ToUpper() | |
if(![string]::IsNullOrEmpty($RequestDigest)) { | |
$request.Headers.Add("X-RequestDigest", $RequestDigest) | |
} | |
if(![string]::IsNullOrEmpty($ETag)) { | |
$request.Headers.Add("If-Match", $ETag) | |
} | |
if($XHTTPMethod -ne $null) { | |
$request.Headers.Add("X-HTTP-Method", $XHTTPMethod.ToUpper()) | |
} | |
if ($Metadata -is [string] -and ![string]::IsNullOrEmpty($Metadata)) { | |
$body = [System.Text.Encoding]::UTF8.GetBytes($Metadata) | |
$request.ContentLength = $body.Length | |
$stream = $request.GetRequestStream() | |
$stream.Write($body, 0, $body.Length) | |
} elseif ($Metadata -is [byte[]] -and $Metadata.Count -gt 0) { | |
$request.ContentLength = $Metadata.Length | |
$stream = $request.GetRequestStream() | |
$stream.Write($Metadata, 0, $Metadata.Length) | |
} else { | |
$request.ContentLength = 0 | |
} | |
$response = $request.GetResponse() | |
try { | |
$streamReader = New-Object System.IO.StreamReader $response.GetResponseStream() | |
try { | |
# If the response is a file (a binary stream) then save the file our output as-is. | |
if ($response.ContentType.Contains("application/octet-stream")) { | |
if (![string]::IsNullOrEmpty($OutFile)) { | |
$fs = [System.IO.File]::Create($OutFile) | |
try { | |
$streamReader.BaseStream.CopyTo($fs) | |
} finally { | |
$fs.Dispose() | |
} | |
return | |
} | |
$memStream = New-Object System.IO.MemoryStream | |
try { | |
$streamReader.BaseStream.CopyTo($memStream) | |
Write-Output $memStream.ToArray() | |
} finally { | |
$memStream.Dispose() | |
} | |
return | |
} | |
# We don't have a file so assume JSON data. | |
$data = $streamReader.ReadToEnd() | |
# In many cases we might get two ID properties with different casing. | |
# While this is legal in C# and JSON it is not with PowerShell so the | |
# duplicate ID value must be renamed before we convert to a PSCustomObject. | |
if ($data.Contains("`"ID`":") -and $data.Contains("`"Id`":")) { | |
$data = $data.Replace("`"ID`":", "`"ID-dup`":"); | |
} | |
$results = ConvertFrom-Json -InputObject $data | |
# The JSON verbosity setting changes the structure of the object returned. | |
if ($JSONVerbosity -ne "verbose" -or $results.d -eq $null) { | |
Write-Output $results | |
} else { | |
Write-Output $results.d | |
} | |
} finally { | |
$streamReader.Dispose() | |
} | |
} finally { | |
$response.Dispose() | |
} | |
} | |
End { | |
} | |
} |
<# | |
.Synopsis | |
Stores the credentials for Invoke-SPORestMethod. | |
.DESCRIPTION | |
Stores the credentials for Invoke-SPORestMethod. This is done so that you | |
don't have to provide your credentials on every call to Invoke-SPORestMethod. | |
.EXAMPLE | |
Set-SPORestCredentials | |
.EXAMPLE | |
Set-SPORestCredentials -Credential $cred | |
#> | |
function global:Set-SPORestCredentials { | |
Param ( | |
[Parameter(ValueFromPipeline = $true)] | |
[ValidateNotNull()] | |
$Credential = (Get-Credential -Message "Enter your credentials for SharePoint Online:") | |
) | |
Begin { | |
if ((Get-Module Microsoft.Online.SharePoint.PowerShell -ListAvailable) -eq $null) { | |
throw "The Microsoft SharePoint Online PowerShell cmdlets have not been installed." | |
} | |
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client.Runtime") | Out-Null | |
} | |
Process { | |
$global:spoCred = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Credential.UserName, $Credential.Password) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This comment has been minimized.
Thanks a lot😄
To check
$spocred
I used this, otherwise powerhsell throw an error variable is undefinedif ( (test-path variable:spoCred) -eq $false){ ... }