introducing the pnp provisioning engine · pdf fileintroducing the pnp provisioning engine ......

9
Introducing the PnP Provisioning Engine Author: Paolo Pialorsi – www.piasys.com - @PaoloPia This short whitepaper introduces the fresh new PnP Provisioning Engine, which has been release in April 2015 within the OfficeDev PnP project, and which will be update in early May 2015. What you will see here is available thanks to the efforts of some of the Office Dev PnP Core Team members ( Vesa Juvonen, Bert Jansen, Frank Marasco, Erwin van Hunen, and me ), as well as the whole OfficeDev PnP community. The goal Let’s start from the main goal of having a provisioning engine. With the introduction of Microsoft Office 365 and Microsoft SharePoint Online, developers are facing the new Cloud App Model (aka CAM) as a new way of creating custom software solutions for Microsoft SharePoint 2013/Online, and Microsoft Office 365 more in general. However, while in the past developers were used to provision custom artifacts using the CAML/XML-based features framework, either with Full Trust Code (aka FTC) solutions or Sandbox So- lutions, now days with the new CAM the approach should be based on provisioning artifacts using the so called “remote provisioning” technique. But what does mean to do “remote provisioning”? It means using the Client Side Object Model (CSOM) to provision artifacts, instead of using the feature framework. Well, and what if I want to model and provision artifacts using a test and a production environment? Or what if I want to automate provisioning of artifacts, just because I want to sell my customizations to mul- tiple customers? Or again, what if I want to define a custom site template that I want to re-use across multiple site instances, like customer-oriented sites, or project-oriented sites? Using the new PnP Provisioning Engine, you can model – even simply by using the web browser – the design of Site Columns, Content Types, List Definitions and Instances, Composed Looks, Pages (either WebPart Pages or Wiki Pages), and much more. When you are done with the design, you can export what you have done into a persistent provisioning template format (XML, JSON, or whatever you like), and you can apply that template to as many target sites as you like. If it sounds interesting … go ahead reading, and let’s learn how to use it! Disclaimer: So far, the OfficeDev PnP Core Team focused its own attention on provisioning against Microsoft SharePoint Online. However in the upcoming weeks and months, we plan to update and improve the engine’s capabilities in order to support on-premises scenarios, providing almost the same capabilities both on the cloud and on-premises. Creating a Provisioning Template As already stated, the easiest way to create a custom provisioning template is to create a fresh new site collection in Microsoft SharePoint Online, to define your artifacts (Composed Look, Site Columns, Content Types, Lists Instances, Pages, Files, etc.) and to save the result as a Provisioning Template. Thus, let’s say you have defined a sample site with a custom look (custom color theme, custom logo, custom background image). You can see the resulting Home Page in the following figure.

Upload: ngominh

Post on 11-Mar-2018

255 views

Category:

Documents


2 download

TRANSCRIPT

Page 1: Introducing the PnP Provisioning Engine · PDF fileIntroducing the PnP Provisioning Engine ... Content Types, List Definitions and Instances, Composed Looks, Pages (either WebPart

Introducing the PnP Provisioning Engine Author: Paolo Pialorsi – www.piasys.com - @PaoloPia

This short whitepaper introduces the fresh new PnP Provisioning Engine, which has been release in April

2015 within the OfficeDev PnP project, and which will be update in early May 2015. What you will see

here is available thanks to the efforts of some of the Office Dev PnP Core Team members (Vesa Juvonen,

Bert Jansen, Frank Marasco, Erwin van Hunen, and me ), as well as the whole OfficeDev PnP community.

The goal Let’s start from the main goal of having a provisioning engine. With the introduction of Microsoft Office

365 and Microsoft SharePoint Online, developers are facing the new Cloud App Model (aka CAM) as a new

way of creating custom software solutions for Microsoft SharePoint 2013/Online, and Microsoft Office

365 more in general. However, while in the past developers were used to provision custom artifacts using

the CAML/XML-based features framework, either with Full Trust Code (aka FTC) solutions or Sandbox So-

lutions, now days with the new CAM the approach should be based on provisioning artifacts using the so

called “remote provisioning” technique. But what does mean to do “remote provisioning”? It means using

the Client Side Object Model (CSOM) to provision artifacts, instead of using the feature framework.

Well, and what if I want to model and provision artifacts using a test and a production environment? Or

what if I want to automate provisioning of artifacts, just because I want to sell my customizations to mul-

tiple customers? Or again, what if I want to define a custom site template that I want to re-use across

multiple site instances, like customer-oriented sites, or project-oriented sites?

Using the new PnP Provisioning Engine, you can model – even simply by using the web browser – the

design of Site Columns, Content Types, List Definitions and Instances, Composed Looks, Pages (either

WebPart Pages or Wiki Pages), and much more. When you are done with the design, you can export what

you have done into a persistent provisioning template format (XML, JSON, or whatever you like), and you

can apply that template to as many target sites as you like.

If it sounds interesting … go ahead reading, and let’s learn how to use it!

Disclaimer: So far, the OfficeDev PnP Core Team focused its own attention on provisioning against

Microsoft SharePoint Online. However in the upcoming weeks and months, we plan to update and

improve the engine’s capabilities in order to support on-premises scenarios, providing almost the

same capabilities both on the cloud and on-premises.

Creating a Provisioning Template As already stated, the easiest way to create a custom provisioning template is to create a fresh new site

collection in Microsoft SharePoint Online, to define your artifacts (Composed Look, Site Columns, Content

Types, Lists Instances, Pages, Files, etc.) and to save the result as a Provisioning Template.

Thus, let’s say you have defined a sample site with a custom look (custom color theme, custom logo,

custom background image). You can see the resulting Home Page in the following figure.

Page 2: Introducing the PnP Provisioning Engine · PDF fileIntroducing the PnP Provisioning Engine ... Content Types, List Definitions and Instances, Composed Looks, Pages (either WebPart

Moreover, you have defined a couple of Site Columns, a Content Type and a Library of Invoices with a

custom View. In the two following figures you can see the result.

Page 3: Introducing the PnP Provisioning Engine · PDF fileIntroducing the PnP Provisioning Engine ... Content Types, List Definitions and Instances, Composed Looks, Pages (either WebPart

In order to export that site as a Provisioning Template, you can use either a bunch of PowerShell Scripting

(thanks to the efforts of Erwin!) or some CSOM code, with some extension methods, which are provided

by the OfficeDev PnP Core Library.

In order to use the PowerShell extensions, you can simply browse to the proper URL (http://aka.ms/of-

ficedevpnpcmdlets16 for Microsoft SharePoint Online) and install the OfficeDev PnP Core PowerShell ex-

tensions. Then, after having connected your PowerShell environment to Microsoft Office 365, by using

the Connect-SPOnline cmdlet, you will be able to use the following PowerShell cmdlet:

Get-SPOProvisioningTemplate -Out "PnP-Provisioning-File.xml"

The –Out argument instructs the cmdlet about where to save the Provisioning Template.

On the other side, in order to use the CSOM extensions, you can simply create any kind (Console, Win-

dows, SharePoint App, whatever you like) of .NET software project, and add the OfficeDev PnP NuGet

Package. The NuGet Package is available in two flavors: OfficeDev PnP Core V15, which targets Microsoft

SharePoint 2013 on-premises, and OfficeDev PnP Core, which targets Microsoft SharePoint Online.

Let’s target the Microsoft SharePoint Online, which so far has been more tested and was the main target

of our efforts. You will simply need to connect to Microsoft Office 365, create a ClientContext instance

and retrieve a reference to a Web object. Thanks to a new extension method, called GetProvisioningTem-

plate, you will be able to retrieve a ProvisioningTemplate object that can be saved using a template pro-

vider and a serialization formatter. Both the template provider and the serialization formatter objects can

be customized, so that you can implement whatever persistence storage and serialization format you like.

Out of the box, the PnP Provisioning Engine provides support for File System, SharePoint, and Azure Blob

Page 4: Introducing the PnP Provisioning Engine · PDF fileIntroducing the PnP Provisioning Engine ... Content Types, List Definitions and Instances, Composed Looks, Pages (either WebPart

Storage template providers, as well as for XML (and upcoming JSON) serialization formatters. In the fol-

lowing figure (credits to Vesa) you can see an outline of the overall architecture of the PnP Provisioning

Engine.

The result of extracting and saving a ProvisioningTemplate instance object will be for instance an XML file

like the one shown in the following XML code excerpt:

<?xml version="1.0"?> <pnp:Provisioning xmlns:pnp="http://schemas.dev.office.com/PnP/2015/05/ProvisioningSchema"> <pnp:Preferences Generator="OfficeDevPnP.Core, Version=1.2.515.0, Culture=neutral, PublicKeyToken=null" /> <pnp:Templates ID="CONTAINER-TEMPLATE-1D3F60898418437E8B275147BEC7B0F5"> <pnp:ProvisioningTemplate ID="TEMPLATE-1D3F60898418437E8B275147BEC7B0F5" Version="1"> <pnp:Security> <pnp:AdditionalAdministrators> <pnp:User Name="i:0#.f|membership|[email protected]" /> </pnp:AdditionalAdministrators> </pnp:Security> <pnp:Files> <pnp:File Src="PnP.png" Folder="SiteAssets" Overwrite="true" /> <pnp:File Src="STB13_Rick_01_small.png" Folder="SiteAssets" Overwrite="true" /> </pnp:Files> <pnp:SiteFields> <Field Type="DateTime" DisplayName="Invoice Date" Required="FALSE" EnforceUniqueValues="FALSE" Indexed="FALSE" Format="DateOnly" Group="PnP Columns" FriendlyDisplayFormat="Disabled" ID="{f1c6f202-f976-4f4e-b0a3-8b984991d00d}" SourceID="{5a15b9ca-4410-4854-bc61-d7fb0ff84e56}" StaticName="PnPInvoiceDate" Name="PnPInvoiceDate" CalType="0"> <Default>[today]</Default> </Field> <Field Type="Text" DisplayName="Invoice Number" Required="FALSE" EnforceUniqueValues="FALSE" Indexed="FALSE" MaxLength="20" Group="PnP Columns" ID="{5049a822-424c-4479-9648-79c4b3214375}" SourceID="{5a15b9ca-4410-4854-bc61-d7fb0ff84e56}" StaticName="PnPInvoiceNumber" Name="PnPInvoiceNumber"> </Field> </pnp:SiteFields> <pnp:ContentTypes> <pnp:ContentType ID="0x01010097931365769EE34E9078576A150FF52E" Name="Invoice" Description="" Group="PnP Content Types"> <pnp:FieldRefs> <pnp:FieldRef ID="5049a822-424c-4479-9648-79c4b3214375" Name="PnPInvoiceNumber" /> <pnp:FieldRef ID="f1c6f202-f976-4f4e-b0a3-8b984991d00d" Name="PnPInvoiceDate" /> </pnp:FieldRefs> </pnp:ContentType> </pnp:ContentTypes> <pnp:Lists> <pnp:ListInstance Title="Invoices" Description="" DocumentTemplate="{site}/Invoices/Forms/template.dotx" TemplateType="101" Url="Invoices"

Page 5: Introducing the PnP Provisioning Engine · PDF fileIntroducing the PnP Provisioning Engine ... Content Types, List Definitions and Instances, Composed Looks, Pages (either WebPart

EnableVersioning="true" MinorVersionLimit="0" MaxVersionLimit="500" TemplateFeatureID="00bfea71-e717-4e80-aa17-d0c71b360101" ContentTypesEnabled="true" EnableAttachments="false"> <pnp:ContentTypeBindings> <pnp:ContentTypeBinding ContentTypeID="0x01010097931365769EE34E9078576A150FF52E" Default="true" /> </pnp:ContentTypeBindings> <pnp:Views> <View Name="{3D715498-8FA2-4B80-8D35-885B2A4CCBDE}" MobileView="TRUE" MobileDefaultView="TRUE" Type="HTML" DisplayName="All Documents" Url="/sites/PnPProvisioningDemo/Invoices/Forms/AllItems.aspx" Level="1" BaseViewID="1" ContentTypeID="0x" ImageUrl="/_layouts/15/images/dlicon.png?rev=38"> <Query> <OrderBy> <FieldRef Name="FileLeafRef" /> </OrderBy> </Query> <ViewFields> <FieldRef Name="DocIcon" /> <FieldRef Name="LinkFilename" /> <FieldRef Name="Modified" /> <FieldRef Name="Editor" /> </ViewFields> <RowLimit Paged="TRUE">30</RowLimit> <JSLink>clienttemplates.js</JSLink> <XslLink Default="TRUE">main.xsl</XslLink> <Toolbar Type="Standard" /> </View> <View Name="{D9BC935E-2154-47EE-A9E2-7C9490389007}" DefaultView="TRUE" MobileView="TRUE" Type="HTML" DisplayName="All Invoices" Url="/sites/PnPProvisioningDemo/Invoices/Forms/All Invoices.aspx" Level="1" BaseViewID="1" ContentTypeID="0x" ImageUrl="/_layouts/15/images/dlicon.png?rev=38"> <Query> <OrderBy> <FieldRef Name="FileLeafRef" /> </OrderBy> </Query> <ViewFields> <FieldRef Name="DocIcon" /> <FieldRef Name="LinkFilename" /> <FieldRef Name="Modified" /> <FieldRef Name="Editor" /> <FieldRef Name="PnPInvoiceDate" /> <FieldRef Name="PnPInvoiceNumber" /> </ViewFields> <RowLimit Paged="TRUE">30</RowLimit> <Aggregations Value="Off" /> <JSLink>clienttemplates.js</JSLink> <XslLink Default="TRUE">main.xsl</XslLink> <Toolbar Type="Standard" /> </View> </pnp:Views> <pnp:FieldRefs> <pnp:FieldRef ID="5049a822-424c-4479-9648-79c4b3214375" Name="PnPInvoiceNumber" DisplayName="Invoice Number" /> <pnp:FieldRef ID="f1c6f202-f976-4f4e-b0a3-8b984991d00d" Name="PnPInvoiceDate" DisplayName="Invoice Date" /> </pnp:FieldRefs> </pnp:ListInstance> </pnp:Lists> <pnp:Features /> <pnp:CustomActions /> <pnp:ComposedLook BackgroundFile="{sitecollection}/SiteAssets/STB13_Rick_01_small.png" ColorFile="{sitecollection}/_catalogs/theme/15/Palette012.spcolor" SiteLogo="{sitecollection}/SiteAssets/PnP.png" Name="RED" MasterPage="{sitecollection}/_catalogs/masterpage/seattle.master" FontFile="" /> </pnp:ProvisioningTemplate> </pnp:Templates> </pnp:Provisioning>

As you can see, the XML elements are almost self-explanatory. The XML schema used in the example

references the 201505 version of the PnP Provisioning Schema (XML Namespace: http://schemas.dev.of-

fice.com/PnP/2015/05/ProvisioningSchema), which has been defined together with the whole OfficeDev

PnP Community, and which can be found on GitHub at the following URL: https://github.com/Of-

ficeDev/Pnp-Provisioning-Schema/. Within the same repository, you will also find a markdown (MD) auto-

generated document, which describes the main elements, types and attributes available to manually de-

fine an XML provisioning template.

Page 6: Introducing the PnP Provisioning Engine · PDF fileIntroducing the PnP Provisioning Engine ... Content Types, List Definitions and Instances, Composed Looks, Pages (either WebPart

However, the real power of this provisioning engine is the availability of a high level and serialization

format independent Domain Model. In fact, internally the PnP Provisioning Engine is completely decou-

pled from any kind of serialization format, and the whole engine simply handles instances of the Provi-

sioningTemplate type. For instance, in the following figure you can see the “Quick Watch” window of

Microsoft Visual Studio 2013 showing a ProvisioningTemplate object instance.

It is up to you to define the ProvisioningTemplate manually, using a model site, or by composing an XML

document that has to be valid against the PnP Provisioning XSD Schema, or by simply writing .NET code

and constructing the hierarchy of objects. You can even do a mix of those approaches: you can design the

provisioning template using a model site, then you can save it into an XML file and do some in-memory

customizations, while handling the ProvisioningTemplate instance in your code.

Applying a Provisioning Template Now that you have seen what a Provisioning Template is, and how to extract the Domain Model object

from an existing site, you are ready to apply it to a target site. Let’s say that you have another fresh new

Site, which for instance is the root site of a new Site Collection in Microsoft SharePoint Online that has

been create using the Team Site template, like it is shown in the following figure.

Page 7: Introducing the PnP Provisioning Engine · PDF fileIntroducing the PnP Provisioning Engine ... Content Types, List Definitions and Instances, Composed Looks, Pages (either WebPart

By default, the site will look like the following figure, which is the default layout of a SharePoint Online

site.

One more time, you can apply a custom ProvisioningTemplate instance object either by using a bunch of

PowerShell scripting, or by writing some .NET code. If you want to use PowerShell, in the following excerpt

you can see the Apply-SPOProvisioningTemplate cmdlet in action.

Page 8: Introducing the PnP Provisioning Engine · PDF fileIntroducing the PnP Provisioning Engine ... Content Types, List Definitions and Instances, Composed Looks, Pages (either WebPart

Apply-SPOProvisioningTemplate -Path "PnP-Provisioning-File.xml"

The –Path argument refers to the source template file, and the cmdlet will automatically apply to the

currently connected site (implied by the Connect-SPOnline cmdlet). In the following figure you can see the

final result.

As you can see, the site has the same look as the original template, and it includes the Invoices library,

with all the provisioning stuff under the cover (Site Columns, Content Types, etc.).

And what about using .NET code? Here is an excerpt about how to use CSOM and the OfficeDev PnP Core

Library extension methods to apply the template.

using (var context = new ClientContext(destinationUrl)) { context.Credentials = new SharePointOnlineCredentials(userName, password); Web web = context.Web; context.Load(web, w => w.Title); context.ExecuteQueryRetry(); // Configure the XML file system provider XMLTemplateProvider provider = new XMLFileSystemTemplateProvider( String.Format(@"{0}\..\..\", AppDomain.CurrentDomain.BaseDirectory), ""); // Load the template from the XML stored copy ProvisioningTemplate template = provider.GetTemplate("PnP-Provisioning-Demo-201505-Polished.xml"); // Apply the template to another site Console.WriteLine("Start: {0:hh.mm.ss}", DateTime.Now); // We can also use Apply-SPOProvisioningTemplate web.ApplyProvisioningTemplate(template); Console.WriteLine("End: {0:hh.mm.ss}", DateTime.Now); }

Page 9: Introducing the PnP Provisioning Engine · PDF fileIntroducing the PnP Provisioning Engine ... Content Types, List Definitions and Instances, Composed Looks, Pages (either WebPart

You simply need to create an instance of Template Provider object, depending on what kind of persistence

you will use to save and load the template. You will have to load the template from the source repository,

by using the GetTemplate method. Lastly, you will apply the template to the target site, using the Apply-

ProvisioningTemplate extension method of the Web type.

On an average, the library will take around a couple of minutes to apply the template, regardless you are

using PowerShell, .NET or whatever else. If you want, you can register a delegate to monitor the overall

process, while the provisioning is in progress. We are still improving performances of the engine, and so

far we have focused our attention on capabilities and functionalities.

Advanced Topics This is just an introductory article, in the near future we will go deeper about some more advanced topics.

Nevertheless, it is important to underline that using the new PnP Provisioning Engine you can also provi-

sion Taxonomies, you can use variables and tokens, which can be replaced at runtime, based on what you

are provisioning (List IDs, Parameters, Terms’ IDs, etc.). You can invoke the provisioning engine from timer

job services, provider hosted apps, external sites, or whatever else. Lastly, you can use the PnP Provision-

ing Engine to move artifacts from test/staging environments to production environments. In the near fu-

ture I will cover this topics, as well.

Wrap Up Please, play with the PnP Provisioning Engine, give us feedbacks using the GitHub site

(https://github.com/OfficeDev/PnP/) or the Yammer network (https://www.yammer.com/itpronet-

work/), and enjoy the future of CAM and remote provisioning!