I’ve installed Windows Server 2012 Release Candidate on my VirtualBox today. Everything worked fine till I installed the Guest Additions, it suddenly became slow and unresponsive from time to time, especially when using Internet Explorer. Because it happened after installing the Guest Additions, I thought it had something to do with the 3D acceleration, so I disabled that and now it works fine.

So, just disable 3D acceleration on the video properties and you’re good to go!

I found an article on the internet that could tell me how I can install SharePoint 2013 on a Windows Server 2012 machine. I however, just want to install the new SharePoint 2013 Preview on an a familiar machine, without all the Windows Server 2012 Preview nonsense.

I cloned an existing SharePoint 2010 virtual machine, with AD and SQL Server 2008 r2 already configured, uninstalled SharePoint Server 2010 and SharePoint Designer 2010 and started from there. This will also work on a newly configured machine, keeping in mind that we are using AD and SQL Server 2008 r2.

On the first attempt to install SharePoint 2013 (download link), the  autorun wasn’t working, so I opened the folder and ran setup.exe. Then I got a message telling me I need a few components:

  • This product requires Microsoft Identity Extensions.
  • This product requires  Windows Server Appfabric. Install Windows Server Appfabric and re-run setup.
  • This product requires Cumulative Update Package 1 for Microsoft AppFabric 1.1 for Windows Server (KB2671763)
  • This product requires Microsoft SQL Server 2008 R2 SP1 Native Client.
  • This product requires the Microsoft WCF Data Services 5.0.
  • This product requires Microsoft Information Protection and Control Client (MSIPC)

So, obviously I forgot to launch the pre-requisites installer first, prerequisiteinstaller.exe.

Now I could install SharePoint 2013 successfully and launch the Configuration Wizard afterwards. But upon configuring the database my system tells me that my SQL server has an unsupported version. I need to apply SP1 of SQL Server 2008 r2: http://www.microsoft.com/en-us/download/details.aspx?id=26727

After completing the configuration wizard, it dropped me into the Central Administration. I tried to run the wizard that generates a complete environment, but it failed and resulted in a corrupt web application. So my advice is, just like SharePoint 2010: skip the wizard and do it manually. I created a new web application and site collection and it works like a charm.

Microsoft has released SharePoint Server 2013 Preview this afternoon, or evening at my time. Download it here: http://technet.microsoft.com/en-US/evalcenter/hh973397.aspx?wt.mc_id=TEC_121_1_33

It’s also possible to get yourself an Office 365 setup with the new Office Suite, including SharePoint Online (yes, SharePoint 2013 Preview). With a few clicks you can walk into your own SharePoint 2013 setup: http://www.microsoft.com/office/preview/en/office-365-enterprise

This is a nasty SharePoint bug which caused some trouble in one of the SharePoint Online environments I was working on.

I created a Site Template using the “Save site as template” feature of SharePoint. Now when I created a new site from the template it resulted in the web parts all mixed up in the Left web part zone. Remarkably it was only the Left zone, the others were keeping their correct web part sequence.

When I took a look in the Onet.xml of the Site Template the web parts were nicely divided into seperate AllUsersWebPart’s and having correct WebPartZoneId’s. And although the web parts were also mixed up in the XML, the WebPartOrder properties were set correctly, 1 for the first, 2 for the second and so on. I still tried to rearrange the XML so the web parts would also have the right sequence in the syntax, but with no success, the web parts were still mixed up.

The final thing to do was to create a Web Part Zone for each Web Part. I did this by opening the page in SharePoint Designer and edit in the Advanced Mode (button on the ribbon).

This way the order is hardcoded on the page. I admit, it’s not very neat, but it does the trick.

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.

EDIT: THIS PROJECT IS CONTINUED ON CODEPLEX!

Due to the success of this post I continued this as a project on CodePlex: https://sharepointpowershell.codeplex.com

 

But if you still want to continue reading this post, go ahead.

How it works

Download this file and extract the DLL to an easy location to reach from PowerShell. Because this assembly uses the Client Object Model you need to install the COM Redistributable as well.

These are the PowerShell commands to run:

You need to run PowerShell in single-threaded mode (the authentication requires it).

powershell -STA

Import the DLL.

[Reflection.Assembly]::LoadFile("D:\ClaimsAuth.dll")

Instantiate a new SPOContext providing your SharePoint Online site URL. (Don’t forget the https)

$spoContext = new-object SPOContext("https://jeffreypaarhuis.sharepoint.com")

Now, let’s test it:

$spoContext = new-object SPOContext("https://jeffreypaarhuis.sharepoint.com")
$web = $spoContext.Web
$spoContext.Load($web)
$spoContext.ExecuteQuery()
Write-Host $web.Title

As you already might understand, this solution is based on the SharePoint Client Object Model. This means that everything that’s possible with the COM is possible to script. This post explains how to work with Sites, Permissions, Documents, etc. with the COM. It is written in C# but it’s fairly easy to translate to PowerShell.

Samples


-------------------
Init spoContext
-------------------

powershell -sta
[Reflection.Assembly]::LoadFile("D:\ClaimsAuth.dll")
$spoContext = New-Object SPOContext("https://mysharepointonline.sharepoint.com")

-------------------
Print sitename
-------------------

$web = $spoContext.Web
$spoContext.Load($web)
$spoContext.ExecuteQuery()
$web.Title

-------------------
Add property to bag
-------------------

$web.AllProperties.FieldValues.Add("propA","Property A")
$spoContext.ExecuteQuery()

$web.AllProperties.Item("propA")
-------------------
Show features
-------------------

$site = $spoContext.Site
$spoContext.Load($site)
$spoContext.ExecuteQuery()
$features = $site.Features
$spoContext.Load($features)
$spoContext.ExecuteQuery()

$features
-------------------
Permissions stuff
-------------------

Function GetWeb
{
 $ctx.ExecuteQuery()
 Return $ctx.Web
}

Function GetList ($name)
{
 $web = GetWeb
 if ($web -ne $null)
 {
 $lists = $web.Lists
 $ctx.Load($lists)
 $ctx.ExecuteQuery()
 $list = $lists | where {$_.Title -eq $name}
 return $list
 }
 return $null
}

Function GetRole ($rType)
{
 $web = GetWeb
 if ($web -ne $null)
 {
 $roleDefs = $web.RoleDefinitions
 $ctx.Load($roleDefs)
 $ctx.ExecuteQuery()
 $roleDef = $roleDefs | where {$_.RoleTypeKind -eq $rType}
 return $roleDef
 }
 return $null
}

Function GetPrincipal ($name)
{
 $web = GetWeb
 if ($web -ne $null)
 {
 $principal = $web.EnsureUser($name)
 $ctx.Load($principal)
 $ctx.ExecuteQuery()
 return $principal
 }
 return $null
}

Function GetGroup ($name)
{
 $web = GetWeb
 if ($web -ne $null)
 {
 $groups = $web.SiteGroups
 $ctx.Load($groups)
 $ctx.ExecuteQuery()
 $group = $groups | where {$_.Title -eq $name}

 return $group
 }
 return $null
}

Function GetDocumentLibrary ($name)
{
 $web = GetWeb
 if ($web -ne $null)
 {
 $docLibs = $web.Lists
 $ctx.Load($docLibs)
 $ctx.ExecuteQuery()
 $docLib = $docLibs | where {$_.Title -eq $name}
 return $docLib
 }
 return $null
}

$web = GetWeb

$web.BreakRoleInheritance($true, $false);
$principal = GetGroup "MyGroup"
$roleType = [Microsoft.SharePoint.Client.RoleType]"Contributor"
$role = GetRole $roleType

$collRdb = new-object Microsoft.SharePoint.Client.RoleDefinitionBindingCollection($ctx)
$collRdb.Add($role)
$collRoleAssign = $web.RoleAssignments
$collRoleAssign.Add($principal, $collRdb)

$ctx.ExecuteQuery()

$list = GetList "Shared Documents"

$list.BreakRoleInheritance($false, $false);
$roleType = [Microsoft.SharePoint.Client.RoleType]"Reader"
$role = GetRole $roleType

$collRdb = new-object Microsoft.SharePoint.Client.RoleDefinitionBindingCollection($ctx)
$collRdb.Add($role)
$collRoleAssign = $list.RoleAssignments
$collRoleAssign.Add($principal, $collRdb)

$ctx.ExecuteQuery()

Errors?

You might see the following errors from time to time, which aren’t a big deal:

– “The requested site does not appear to have claims enabled or the Login Url has not been set.”.
Problem: This usually means that no session can be instantiated (SharePoint Online bug).
Solution: Navigate to your site in Internet Explorer, when your site doesn’t show, refresh it a few times until it shows, or go to https://portal.microsoftonline.com. When you get a login page, go back to your script.

– “The remote name could not be resolved: ‘mysp.sharepoint.com'”
Problem: During scripting, the context timed out.
Solution: Re-instantiate the $spoContext object. When running a script in one go, this error shouldn’t pop because the Context will not prematurely expire.

Under the hood

How does it work under the hood? What’s in the DLL? What makes SharePoint Online so difficult?

In line with this one I’ve written a post that explains what the problem with SharePoint Online is and how to build your own DLL. Read it here.

UPDATE (11-7-2012):

Forgot to mention you need to install the COM Redistributable.

UPDATE (3-9-2012):

Added samples.

I’m sorry

June 6th, 2012 | Posted by Jeffrey Paarhuis in General Talk - (2 Comments)

Erika Andersen has written an article about apologizing. Doing it the wrong and the right way.

Normally I don’t post these kinds of things, but because I agree so very much with this article I want to put it in the spotlights, right here.

People apologizing with “I’m sorry, but..” or “I apologize you didn’t understand…” can really really really annoy me. They apologize first, but then instantly switch to defense mode trying to talk their way out of it. I wonder if these people know how untrustworthy they sound.

The article writes about apologies of leaders and their respect, but I think the ‘apology primer’ applies to everyone.

Here is the article: http://www.forbes.com/sites/erikaandersen/2012/06/05/courageous-leaders-dont-make-excuses-they-apologize/

According to a tweet from Maarten Visser about the Microsoft Office roadmap, we can assume a beta of SharePoint 15 will come halfway 2012 and the release early 2013.


Image from Maarten Visser’s Tweet

If you want to know more about the new features of SharePoint 15, read this post.

I was fighting with this all day long.

I created a WCF service project (the host) and placed the ServiceContract (Interface) in a separate assembly. In another project (the consumer) I referenced that assembly and generated a proxy, with add service reference, and made sure the “reuse types in referenced assemblies” was checked. It then generated the proxy, but not using my handmade interface. To be entirely clear: it is generating an interface, but not using mine from the referenced assembly.

That’s weird, I thought I checked reuse types? So I tried it over and over with different settings, endpoints and cups of coffee, but with no success. So at the end of the day I googled a bit and found out that the “reuse types in referenced assemblies” only applies to DataContracts and not to ServiceContracts! Doh!

So, is it a bug or is it a feature? Well, to me it makes no sense that ServiceContracts don’t get reused, so in my opinion it’s a bug.

What are our options then? Not using the “add service reference”, but doing it manually with a few lines of code, which is also a bit neater:

// Supply the binding and address in code
Binding binding = new BasicHttpBinding();
EndpointAddress address = new EndpointAddress("http://tempuri.org/address");
IServiceContract channel = ChannelFactory.CreateChannel(binding, address);

// Or read them from the config file
ChannelFactory channelFactory = new ChannelFactory();
IServiceContract channel = channelFactory.CreateChannel();

I looked for hours! I can’t find this thing anywhere else on the internet! There must be a complete group of developers and designers that have been struggling with this before! I can’t believe I’m supposed to be the first one to put this solution on the world wide web.

All I wanted to do is to disable the wordwrap in a specific div in SharePoint, like so:

white-space: nowrap;

It worked perfectly in all browsers, except for… That’s right! Internet Explorer!

After struggling for half a day I finally found out that SharePoint inserts another piece of styling called word-wrap. This is the SharePoint code:

word-wrap: break-word;

All I had to do is override this in my own style and voila, it finally works!

And now the working style looks like this:

white-space: nowrap;word-wrap: normal;