Earlier this summer I mentioned that I’d start blogging about some of my scripts that I have in my toolbox and I guess I’m a little behind in that but I guess better late than never. I’ve had snippets of code that I could use to make REST based calls to SharePoint Online for a while, some of them were little snippets of PowerShell and some were embedded deep in my custom cmdlets or some other application that I’ve created over time. I recently stumbled across an article by Vadim Gremyachev where he provided his script for making a REST call using PowerShell and decided that I’d go ahead and provide my version of that same script (which I tweaked to add a couple minor parameters that Vadim included in his).
Before I walk through the key points of the script let me first share it with you:
The first thing you have to know about working with SharePoint Online REST endpoints is that you have to get connected to the service. This is done by passing your credentials (username and password) to a new instance of the Microsoft.SharePoint.Client.SharePointOnlineCredentials object. This object handles the conversion of our simple username and password to the appropriate authorization token and cookies necessary to establish the connection (and it is these additional complexities which makes it not possible for us to utilize the Invoke-RestMethod PowerShell V3 native cmdlet). Because I don’t want to have to deal with providing the username and password every time I run a command or otherwise remembering what variable I stored the credentials in I chose to utilize a global variable ($global:spoCred) which I check in the Begin block of the function and if it’s not set then I prompt for the credentials and then set the variable. I also chose to create another set of functions, Set-SPORestCredential and Clear-SPORestCredential, to make it easier to work with this variable (so you can explicitly set the variable using the Set-SPORestCredential function or clear the variable using the Clear-SPORestCredential function). Using this approach I can set my credentials just the once and then run my REST calls over and over without having to worry about reauthorizing.
In order to utilize the Microsoft.SharePoint.Client.SharePointOnlineCredentials object you have to either load the Microsoft.SharePoint.Client.dll and Microsoft.SharePoint.Client.Runtime.dll assemblies or you can take the approach I did which was to assume that the Microsoft SharePoint Online Cmdlets are installed and simply load the Microsoft.Online.SharePoint.PowerShell module which results in the types I need being loaded into memory. So if you don’t have the module installed then my function will throw an error stating as such.
From there the rest is pretty straightforward as I just use a System.Net.WebRequest object and set the appropriate variables and header values to make the request. Once I get a result back I check the expected verbosity result (a new JSON Lite feature) and use the ConvertFrom-Json cmdlet to output the results as a PSObject. Note that this is a pretty simple implementation in that I’m assuming the results that come back are a JSON object and not something like a binary stream as the result of retrieving a file or something. For a solution that is more complex and handles binary objects in the return use my cmdlet by the same name (Invoke-SPORestMethod) included with my SharePoint Online custom cmdlets download. Also, the –Metadata parameter is another simplistic approach which and doesn’t take into account some of the more complex scenarios – my custom cmdlet replaces the –Metadata parameter with a –Body parameter (though it’s aliased as Metadata) and handles a wider range of possibilities for posting data to the REST endpoint.
Because the SharePoint Online REST API is able to grow quickly without the need for Microsoft to post updated installs, such is the case with the CSOM library, the need to utilize this API for automating tasks using PowerShell will grow just as quickly if not more so. Because of this it is extremely valuable to have a quick and easy way to make RESTful calls without having to recreate all this plumbing every time. It is because of this that I created this script and, more specifically, why I added the equivalent yet more robust version of the script as a custom cmdlet. So in summary, I strongly recommend you get used to using the REST API and this script and equivalent cmdlet will make it that much easier for you to do so.