SharePoint REST API
Because REST services are much simpler than other frameworks for communicating with web applications, they have gained a great deal of traction over the past half-decade or so. This is no exception in SharePoint, and the SharePoint REST API which began with SharePoint 2010 has increased its capabilities greatly over time.
While REST services may be more familiar and useful to C# or JavaScript programmers, it is not impossible to connect to them from PowerShell. Here, we'll show you a simple example of how this can be done.
For brevity, the code here builds on the previous CSOM example. You'll need to ensure that $SpoCredential and $WebUrl have valid values.
We start by forming a REST URL. These follow a standard convention, starting with the website URL followed by /_api and a REST query. In our example, we'll use web/lists as our query to return information about the lists and libraries in our SharePoint site:
$RestUrl = "$WebUrl/_api/web/lists"
$Accept = "application/json;odata=verbose"
$ContentType = "application/json;odata=verbose"
[Microsoft.PowerShell.Commands.WebRequestMethod]$Method = [Microsoft.PowerShell.Commands.WebRequestMethod]::Get
Next, we create the web request and assign its properties, including the method GET.
Note the commented sections which apply to other types of REST calls such as POST, PUT, and MERGE. When you're ready to try more sophisticated REST operations like these, there are plenty of great examples online:
$request = [System.Net.WebRequest]::Create($RestUrl)
$request.Credentials = $SpoCredentials
$request.Headers.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f")
$request.ContentType = $ContentType
$request.ContentLength = 0
$request.Accept = $Accept
$request.Method = $Method
<# Skip these for now; this is a simple example
$request.Headers.Add("X-RequestDigest", $RequestDigest)
$request.Headers.Add("If-Match", $ETag)
$request.Headers.Add("X-HTTP-Method", $XHTTPMethod)
# This is for methods such as POST where we need to send some data
If ($Metadata -or $Body) {
If ($Metadata) {
$Body = [byte[]][char[]]$Metadata
}
$request.ContentLength = $Body.Length
$stream = $request.GetRequestStream()
$stream.Write($Body, 0, $Body.Length)
}
#>
Now that we've assembled our request, we can execute it and get the response back from the SharePoint server. We have to do a lot of packing and unpacking, since these objects implement IDisposable. Again, sections we don't need for this example are commented, but have been left in place to help you understand the more complex response processing:
# Process REST Response
$response = $request.GetResponse()
Try {
If (!$BinaryStringResponseBody) { # Always false in our example
$streamReader = New-Object System.IO.StreamReader
$response.GetResponseStream()
Try {
$data = $streamReader.ReadToEnd()
$results = $data | ConvertFrom-Json
# output to the console
$results.d
} Finally {
$streamReader.Dispose()
}
} <# Else { # $BinaryStringResponseBody
$dataStream = New-Object System.IO.MemoryStream
Try {
# Steam-CopyTo isn't implemented in this example
Stream-CopyTo -Source $response.GetResponseStream()
-Destination $dataStream
# output to the console
$dataStream.ToArray()
} Finally {
$dataStream.Dispose()
}
} #>
} Finally {
$response.Dispose()
}
In the preceding command, $data holds the raw response from the server and $results is the converted JSON object.
Readers familiar with REST and PowerShell outside of SharePoint may wonder why we do not use Invoke-WebRequest to make this call. While this should be possible, the call will fail to convert $SpoCredentials; using $Credentials alone will result in a 403 error.
Here's our complete REST request and the response output:
Let's extend this example to display the title for each SharePoint list from the $results.d variable. At first, if you dig into this collection, it may not be so obvious how to get this information. The data we want is contained in $results.d.results. Retrieving it in PowerShell is extremely easy; it can be done with just one line of code:
$results.d.results | Select Title
Likewise, you can read other well-known list properties, such as description.
The preceding example uses a simple GET request to read data. It can't handle POST requests, nor does it interpret the results correctly if the response is a binary stream. REST calls can get fairly complex—sometimes even more so than CSOM calls.
Despite the simplistic nature of the previous code, it demonstrates that REST can be used to obtain quite a lot of data from SharePoint using just a few lines of code. And, unlike CSOM, no special DLLs were required to make this work. It can be quite a useful tool to add to your SharePoint utility belt.