Deep Dive Office 365 API for SharePoint Sites service

Yesterday another DIWUG event! This is a monthly community event in The Netherlands. Albert-Jan Schot (Appie) did a presentation on the Office 365 Groups and I presented a session about the Office 365 API for SharePoint Sites service.

You can find my slide deck on SlideShare, http://www.slideshare.net/bramdejager/deep-dive-into-office-365-apis-for-sharepoint-site-services.

All demos together resulted in a single code base which you can download here.

The SharePoint CSOM assemblies and the “The specified module could not be found” error

When working on my community project SharePoint Client Browser I received multiple times the issue which related to the error message “The specified module could not be found”. The error log shows the error is thrown while authenticating with SharePoint Online.

File '' not found, check log file for detailed information. System.IO.FileNotFoundException: The specified module could not be found. (Exception from HRESULT: 0x8007007E) at Microsoft.SharePoint.Client.Idcrl.ManagedIdcrl.EnsureInited() at Microsoft.SharePoint.Client.Idcrl.ManagedIdcrl.LogonIdentity(String username, SecureString password) at Microsoft.SharePoint.Client.SharePointOnlineCredentials..ctor(String username, SecureString password) at SPBrowser.Entities.TenantAuthentication.InitClientContext()

What is weird about this, although a FileNotFoundException is thrown, the exception details do not indicate which file is actually missing. #Fail!

What also did not help with resolving my issue was missing automated packaging of the SharePoint Client Browser tool. This is definitely one of those reasons to automate your build process. To ensure the package contains everything it needs, instead of missing a single file due to manual packaging.

So, we do we actually need? When building a solution based on the SharePoint CSOM we require a set of assemblies. Depending we are building for SharePoint 2013 (v15) or SharePoint Online (v16) we need a different set. But what was causing the issue was not one of the CSOM assemblies!

Required assemblies for both SharePoint v15 and v16:

  • MSOIDCLIL.DLL
  • MSOIDRES.DLL

SharePoint CSOM assemblies:

  • Microsoft.SharePoint.Client.dll
  • Microsoft.SharePoint.Client.Runtime.dll
  • Microsoft.SharePoint.Client.Taxonomy.dll

Whatever you release in a package, make sure you include the MSOIDCLIL.DLL and MSOIDRES.DLL assemblies!

Developing hybrid SharePoint apps that run on-premise and in the cloud – ESPC 2014

My session at the European SharePoint Conference (#ESPC14) was around developing hybrid apps with the SharePoint App Model. Below you can find the slide deck and PowerShell scripts I used during the demo.

Before you start building hybrid apps who are depending on the authentication done by Azure Control Services (ACS) you need to setup a trust between your on-premise farm and ACS.

  1. Replace the default STS certificate and reboot machine afterwards (Replace-STSCertificate.ps1)
  2. Install Microsoft Online Services Sign-In Assistant for IT Professionals RTW (64-bit), http://www.microsoft.com/en-us/download/details.aspx?id=41950
  3. Install Microsoft Online Services Module for Windows PowerShell (64-bit), http://go.microsoft.com/fwlink/p/?linkid=236297
  4. Run script to connect on-premise SharePoint farm to ACS (Connect-SPFarmToAAD.ps1)

Some important side notes:

  • When replacing the STS certificate, all current trusts who are depending on the STS become invalid. Meaning you have to recreate your existing Trusted Security Token Issuers (Install-TrustedSecurityTokenIssuer.ps1 & Remove-TrustedSecurityTokenIssuer.ps1)
  • Ensure you are using the RTW version of Microsoft Online Services Sign-In Assistant instead of the BETA (which is linked in the TechNet article)

Download PowerShell scripts.

Scripts originate from How to: Use an Office 365 SharePoint site to authorize provider-hosted apps on an on-premises SharePoint site (http://msdn.microsoft.com/en-us/library/office/dn155905(v=office.15).aspx), I don’t own the scripts but only provide them for easy of use.

Develop, Build, Package and Deploy Apps for Office 2013 with Visual Studio 2013–European Office 365 Connect

On April 1st and 2nd in Haarlem (The Netherlands) the first European Office 365 Connect took place. Speakers from over the world (like Dan Holme, Seb Matthews, Marc Reguera and many more) visited Haarlem and did sessions related to Office 365.

I’ve done a session about Apps for Office together with Visual Studio 2013. This was a kind of follow-up session for “The New SharePoint Online Apps – Napa in Action” from Patrick Lamber. You can find my slide deck below.

The demo was around building a Wikipedia Task Pane app which leverages the Wikipedia API for searching Wikipedia. Below a screenshot of the Task Pane App for Office inside the Word 2013 (desktop) client.

Wikipedia Task Pane app inside Word 2013 client

Once the app was done it’s deployed to Windows Azure via a Web Deploy package and the XML manifest is made available to end-users to consume from the Corporate Catalog (hosted in SharePoint Online). After configuring the Office client the Corporate Catalog is available from within Word, Excel, PowerPoint.

Apps for Office catalog in Word (desktop) client

Download the demo sources here: http://1drv.ms/1pTuGx9

SharePoint Online Tenant URLs

Setting up your Office 365 environment and looking for the entry URLs? Below you can find the URLs related to your company SharePoint Online tenant.

Commonly used URLs for a SharePoint Online tenant:

Other URLs related to Office 365:

Using CSOM and PowerShell to query SharePoint Online or on-premise

Recently I released the SharePoint Client Browser (preview) that provides inside in a remote SharePoint site by using the Client Side Object Model (CSOM). The tool only reads data and shows it in a rich interface. When you want to make changes you have options: 1) build a custom tool and use the CSOM to interact with SharePoint or 2) use PowerShell and CSOM to interact with SharePoint.

This post shows how to use PowerShell and CSOM together to interact and automate configuration changes to your SharePoint. The example script can be used for both SharePoint Online and on-premise deployments.

This PowerShell script will be a new feature in the SharePoint Client Browser. This allows the user to start PowerShell directly from the SharePoint Client Browser and eliminates the need to do the scripting discussed in this post by yourself!

Prerequisites

Besides having a SharePoint site collection somewhere, you need to create a folder on your local machine. This folder needs to have the SharePoint Client Runtime assemblies. These can be downloaded here. Next to the SharePoint Client Runtime you need to place your scripts here (for example: OpenSite.ps1).

Folder (on local machine) with prerequisites

The PowerShell script

The easiest way to get started is creating a new TXT-file in the local folder and rename it to “OpenSite.ps1” (or choose a more appropriate name). Next right click with your mouse on the file and choose Edit. This will open up the Windows PowerShell ISE and you can start editing your script.

Authentication

The script is pretty easy and almost reusable for both SharePoint Online and on-premise, but it has a difference between them. Guest what it is?! The authentication is done differently. Below 3 different authentication examples.

Current user credentials

By not providing any credentials automatically the current user credentials are used.

SharePoint Online

When connecting to SharePoint Online you can use the new SharePointOnlineCredentials class. This makes it a lot easier then with SharePoint 2010.

$ctx = New-Object Microsoft.SharePoint.Client.ClientContext($siteUrl) $ctx.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($loginname, $pwd)

SharePoint (on-premise) and credentials

Setting the credentials is done via the NetworkCredential class. That looks like this:

$ctx = New-Object Microsoft.SharePoint.Client.ClientContext($siteUrl) $ctx.Credentials = New-Object System.Net.NetworkCredential($loginname, $pwd)

The full example script

Below you can find the PowerShell script to use with SharePoint Online. Make sure when using the script you choose the right authentication model (see above). After running this script you can use the CSOM the same way as you would use CSOM in your C# application.

$loc = "C:\Users\Bram\Downloads\SharePoint" # Location of DLL's $siteUrl = "https://contoso.sharepoint.com" $loginname = "bram@contoso.onmicrosoft.com" Set-Location $loc Add-Type -Path (Resolve-Path "Microsoft.SharePoint.Client.dll") Add-Type -Path (Resolve-Path "Microsoft.SharePoint.Client.Runtime.dll") Write-Host "Please enter password for $($siteUrl):" $pwd = Read-Host -AsSecureString $ctx = New-Object Microsoft.SharePoint.Client.ClientContext($siteUrl) # Remove or replace line below to change authentication method $ctx.Credentials = New-Object System.Net.NetworkCredential($loginname, $pwd) $web = $ctx.Web $ctx.Load($web) $ctx.ExecuteQuery() Write-Host " Current web title is '$($web.Title)', $($web.Url)"

Slide deck and demos SharePoint Saturday 2013 Holland (#SPSNL13)

Last Saturday I presented at the SharePoint Saturday Holland 2013. It was a good vibe and the audience made it an interactive session. Below you can find the slide deck and parts of PowerShell scripts and source code which I used during my demos.

SharePoint Saturday Holland 2013

Developing hybrid SharePoint apps that run on-premise and in the cloud

With the new SharePoint App model running outside the SharePoint worker process it introduces new authentication models. As a developer you don’t want to build multiple versions of the same app implementing each authentication model separately. This session explains the differences between securing SharePoint apps with OAuth in Office 365 and S2S High Trust in on-premise deployments. You will learn how to build a single app that will run on-premise, online and hybrid SharePoint environments.

Demo: Configure the on-premise SharePoint with Trusted Security Token Issuer

To support high-trust (S2S) apps you need to configure the Trusted Security Token Issuer in your on-premise SharePoint farm. This script is used during the demo to configure the SharePoint farm.

Add-PSSnapin Microsoft.SharePoint.PowerShell -ea 0 # Get the .cer file that you want to use with your app. $certificate = Get-PfxCertificate "C:\Apps\AppCertSP2013.cer" # Get the issuer ID of your app. All the letters in the issuer ID GUID must be lowercase. $issuerId = 'a58e2347-0ead-4ba0-b4b7-75120aa09e4e' # Get the current authentication realm for your SharePoint site $realm = Get-SPAuthenticationRealm -ServiceContext "http://vm-sp-01/sites/dev" # Get the issuer ID together with the realm value. $fullIssuerIdentifier = $issuerId + '@' + $realm # Create a trusted security token service. This fetches metadata from your app (for example, the certificate) and establishes trust with it, so that SharePoint 2013 can accept tokens that are issued by your app. New-SPTrustedSecurityTokenIssuer -Name $issuerId -Certificate $certificate -RegisteredIssuerName $fullIssuerIdentifier –IsTrustBroker

Demo: Build Hybrid app with a single codebase for on-premise and cloud

My last demo was building a Hybrid app that consists of a single codebase which runs both on-premise and in the cloud. The logic which determines if SharePoint is hosted in on-premise or in the cloud is below.

public partial class Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { Uri hostWeb = new Uri(Request.QueryString["SPHostUrl"]); string contextTokenString = TokenHelper.GetContextTokenFromRequest(Request); if (string.IsNullOrEmpty(contextTokenString)) { using (var clientContext = TokenHelper.GetS2SClientContextWithWindowsIdentity(hostWeb, Request.LogonUserIdentity)) { clientContext.Load(clientContext.Web, web => web.Title); clientContext.ExecuteQuery(); Response.Write(clientContext.Web.Title); } } else { using (var clientContext = TokenHelper.GetClientContextWithContextToken(hostWeb.OriginalString, contextTokenString, Request.Url.Authority)) { clientContext.Load(clientContext.Web, web => web.Title); clientContext.ExecuteQuery(); Response.Write(clientContext.Web.Title); } } } }