PowerShell for SharePoint Online: Under the hood

June 14th, 2012 | Posted by Jeffrey Paarhuis in Configuring | Developing

In an earlier post I’ve explained that it’s possible to use PowerShell for SharePoint Online. In this post I want to explain what the difficulties of SharePoint Online are and how we did manage to overcome that.

So, what’s the problem?

When you use the Client Object Model directly from PowerShell, it might seem to work, up to the point that you’re executing a query. Then you will receive a 403 – forbidden error.

Off course, when you don’t provide any credentials you will not get access. You could try to provide a username, password and domain programmatically, but you won’t find any way to authenticate. This is because the authentication method of SharePoint Online differs from the ones that Client Object Model supports.

What’s the solution?

The only thing we have to do is get an authenticated ClientContext and we’re ready to script. Fortunately, Microsoft has done all the hard work, because they have published a sample project for authentication with SharePoint Online.

We are going to pimp this project with our own code and make it possible to retrieve and use an authenticated ClientContext in PowerShell.

Go ahead, download sample project and open the ClaimsAuth solution file in Visual Studio. You will see that it also loads a project called Sp_Ctx; you can remove or just ignore it, we won’t use it.

Now, in the ClaimsAuth project add a new class called “SPOContext” and use the following code:

using System.Net;
using Microsoft.SharePoint.Client;
using MSDN.Samples.ClaimsAuth;

public class SPOContext : ClientContext
{

  public SPOContext(string siteUrl) : base(siteUrl)
  {
    // this method gives a popup asking for credentials
    CookieCollection cookies = ClaimClientContext.GetAuthenticatedCookies(siteUrl, 0, 0);

    this.ExecutingWebRequest += delegate(object sender, WebRequestEventArgs e)
    {
      e.WebRequestExecutor.WebRequest.CookieContainer = new CookieContainer();
      foreach (Cookie cookie in cookies)
      {
        e.WebRequestExecutor.WebRequest.CookieContainer.Add(cookie);
      }
    };
  }

  // need a plain Load method here, the base method is some
  // kind of dynamic method which isn't supported in PowerShell.
  public void Load(ClientObject objectToLoad)
  {
    base.Load(objectToLoad);
  }
}

As you can see, we made an object that inherits from the ClientContext. The magic happens in the constructor; a pop-up will be shown where the user can login with his credentials. It then receives a few cookies which are stored and sent with each request. The cookies are the fairy dust in all of this, the cookies make it possible to authenticate with each request.

You also see a Load method. Why do we need this? The base class already has a Load method! Yes, but that method is some kind of dynamic method which isn’t supported in PowerShell. This custom Load method now acts as a wrapper for the real Load method.

This is it! Build the project and test the ClaimsAuth.dll according to my previous post.

You can follow any responses to this entry through the RSS 2.0 You can leave a response, or trackback.

7 Responses

  • Pingback: Scripting SharePoint Online with PowerShell using Client Object Model | Jeffrey Paarhuis SharePoint Blog

  • Carry Megens says:

    Hi Jeffry, great you figured this out ans shared the info. Can you give an example how to retrieve the user info using powershell?

  • Joseph says:

    Hi Jefferey! This is very impressive code for me after realizing I was hitting a wall with cmdlet’s not working in Sharepoint online. I found many Powershell Scripts that can take a bulk import of URL to create several sites, but it does not work in Sharepoint online. Is there a simplistic way just to perform a bulk import to create a bulk site output within SharePoint online?

    I ran the code and was able to display the name of the SharePoint online sub-site correctly! 🙂

    I have standard Site Template that I need to replicate over hundreds of sites. Any advice is welcome please. Thank you!

    Cheers!

    • Hey Joseph, with this code you could accomplish some automation in the deployment process. I don’t know what you exactly mean, but if you’re talking about exporting and importing entire SiteCollections in Office365, then it will be possible. It will however take a lot of scripting and testing. You’re better of putting some effort in a piece of software that does the exporting and importing for you. I’ve had a good experience with Thinkscape Site Builder.

      Please let me know what you’re trying to accomplish and I will see if I can be of any help.

      Regards!

      • Joe says:

        Thanks Jefferey for the prompt response. Yes, this is to perform the import of URL’s and their naming conventions as sub-sites in SharePoint Online. Many of cmdlets for SharePoint server do not work for SPO. I am attempting to perform the bulk import to create hundreds of sub-sites. I have not had much success in finding a snippet of code that performs this feat. I will check Thinkscape now. Let me know if you have any other ideas. Thank you!

        • Joe says:

          The utility from Thinkscape is provides me with a simple utility to move files into the SP Online site. But one at a time. I was hoping to be able to create around ~800 sites. With ThinkScape I would need to the same operation 800 times repetative. If there were any way to take a CSV file with the name of the subsites and permissions like in:

          http://spcreatesitesfromcsv.codeplex.com/

          and run this in SPO is all that I am hoping for. But some of the commands, they don’t work within the Powershell scripting environment and/or don’t work in SPO at all.



Leave a Reply

%d bloggers like this: