Build your PnP Site Provisioning with PowerShell in Azure Functions and run it from Flow

What if I tell you - you can build your own Azure Function and use PnP to provision SharePoint Online sites without firing up Visual Studio?

What if I tell you - we will follow the best practices from PnP.  And You can do this all within 10 minutes (OK I timed it - if you don't take any breaks it'll be 10 minutes), and we'll do it with PnP PowerShell.

You will think - this is magic.  You will probably say, this is all crazy.

What if I tell you - you can connect this to the newly released Microsoft Flow.  So you don't even need to learn WebHooks (which is awesome and you should learn it).

What if I tell you - the whole thing will cost you a little bit.  It's not totally free.  It will cost you may be two cents.  ($0.02)

You will say, get out.  I need to lie down.

Learning Software pieces like LEGO blocks

I see software pieces as I see LEGO blocks.  PnP Provisioning is a block (a .NET library written in C#).  PowerShell cmdlets are a block.  And Azure Functions is a block.  Flow is a block.

What would happen if you connect them together?

 

Setting up PowerShell from PnP

First, this is how we set up in our local machine:

Install-Module SharePointPnPPowerShellOnline

Why PowerShell? 

Why PowerShell, you ask - John you are a developer.  You are a .NET developer before you became a JavaScript developer.  Why PowerShell suddenly?

The answer is simple.  It is because everybody understand this:

# connect to the SPWeb context
Connect-SPOnline -url "https://sharepointgurus365.sharepoint.com/sites/projects/template"
# export (copy) a template
Get-SPOProvisioningTemplate -force -out project-template.xml

# connect to new blank SPWeb
Connect-SPOnline -url "https://sharepointgurus365.sharepoint.com/sites/projects/tea"
# paste the template
Apply-SPOProvisioningTemplate -path project-template.xml

Four lines - you have just copied a template from /projects/template and stamp it over to /projects/tea - this is the power and the hardwork of the PnP provisioning team.  They make this magic look simple.

PnP was updated about a week after the blogpost and several PnP commands have been renamed to avoid confusion with SharePoint admin commands. See PnP-PowerShell documentations.

Connect-SPOnline is now Connect-PnPOnline
Get-SPOProvisioningTemplate is Get-PnPProvisioningTemplate 
etc

A way to verify the powershell is to run it first on your local machine and make sure it works first, before uploading the same DLL modules and script to Azure Function.

Special thanks to @pskelly

 

But you can do this in C#

Of course, you can also do this in C#, it looks like this:

This shouldn't be too scary to a developer.  But everyone sees the bubbles and the flow chart and just stop trying.  It "looks" hard.

Additionally, in CSOM - everything is asynchronous.  C# makes this simpler with the await syntax, but in the PowerShell cmdlets, every request is essentially serialized - so they are easy to understand, even if they aren't the fastest way. 

If you want to see what this looks like in NodeJS - I have several blogs.  It's great to learn.  If you don't like JavaScript to begin with - then you'll probably run to PowerShell with open arms.

OK enough chatter - let's go back to the demo.

 

Setting up Azure Functions

Create a new HTTP Request function - select PowerShell as the language.

It says Experimental - what they really should say is "The World's Not Ready For This".

PowerShell Azure Functions looks like this.  The request is passed in as raw JSON content - which is parsed into an object.

Output from the function by writing out to the $res file.

 

Install-Module

install-module doesn't work.  But we still can have modules.

http://stackoverflow.com/questions/37724769/how-to-install-a-powershell-module-in-an-azure-function/39985646#39985646  - The steps are explained by Azure Function team's @tohling

Essentially, we can take a PowerShell Module, find all its component script and DLL, and copy them to a modules/ subfolder within the Azure Function.  It will be loaded when the function needs to run.

In Functions - go to Kudu

Navigate to your new function's directory, and add a modules subfolder

In your PC:

Navigate to

C:\Program Files\WindowsPowerShell\Modules\SharePointPnPPowerShellOnline\2.8.1610.1\

(if you don't have this folder - you missed Install-Module SharePointPnPPowerShellOnline from earlier)

You will also need Microsoft.IdentityModel

C:\Windows\assembly\GAC_MSIL\Microsoft.IdentityModel
C:\Windows\Microsoft.NET\assembly\GAC_MSIL\Microsoft.IdentityModel.Extensions

Grab all these DLLs and PowerShell script and throw them all inside modules.

 

Change Azure Function to x64

One more thing.  The PowerShell cmdlets prefer x64 architecture.  Azure Functions provide 32 bit by default.  Switch this in function settings > application settings > Platform

 

Setup Done!

Now we can write fun functions!  Go back to our site provisioning function.

$requestBody = Get-Content $req -Raw | ConvertFrom-Json

# {
#     "source": "https://sharepointgurus365.sharepoint.com/sites/demo02/projects/pst",
#     "destination": "https://sharepointgurus365.sharepoint.com/sites/demo02/projects/tea"
# }

$source = $requestBody.source
$destination = $requestBody.destination

$secpasswd = ConvertTo-SecureString $env:SPO_P -AsPlainText -Force
$mycreds = New-Object System.Management.Automation.PSCredential ($env:SPO_U, $secpasswd)

Connect-SPOnline -url $source -Credentials $mycreds 
Get-SPOProvisioningTemplate -force -out "D:\home\site\wwwroot\project-template.xml"

Connect-SPOnline -url $destination -Credentials $mycreds 
Apply-SPOProvisioningTemplate -path "D:\home\site\wwwroot\project-template.xml"

Out-File -Encoding Ascii -FilePath $res -inputObject "Done $destination"

Note: PnP was updated about a week after the blogpost and several PnP commands have been renamed to avoid confusion with SharePoint admin commands. See PnP-PowerShell documentations.

Connect-SPOnline is now Connect-PnPOnline
Get-SPOProvisioningTemplate is Get-PnPProvisioningTemplate 
etc

A way to verify the powershell is to run it first on your local machine and make sure it works first, before uploading the same DLL modules and script to Azure Function.

Special thanks to @pskelly

The script will run unattended.  So you will need to provide your username/password stored in Function Settings and read from $env variables.

Run success!

What do we have here?!  PowerShell cmdlets that wrapped the PnP C# library and talks to SharePoint Online and everything running inside an Azure Function.

You have a service.

If you are counting lines - there is 10 lines of PowerShell - including the function wrapper.

 

Flow

Let's top off this demo with a Microsoft Flow - this was GA'ed just this week.

Create a list "Copy-Site" - with two fields "ToSite" and "FromSite"

Have the flow trigger off ItemAdded, and call our Azure Function via the Http Request.

Pass in source and destination.

 

Test Flow... workflow

Flow tells you what was sent to the HTTP Request, and what Response body it got back.  Use this for debugging your functions.

 

We always talk Costs because Azure Function is cheap

The 11cents total is over several days, and the breakdown shows it's almost entirely bandwidth costs - which doesn't have a free bucket.  My AzureFunctions don't exceed the allowed free tier, so I'm not paying for any compute time.

 

Where do we go from here?

What can you do with PowerShell?  Desired State Configuration?  Download lists to CSV?  Synchronize and fix metadata?  Locate orphaned or misplaced documents and fix that?  Improve and merge user profile properties?  Provision users and sites and what else do you fancy?

Does this give you wild ideas?

 

Azure Functions is Serverless

When we say Azure Functions is Serverless - it always seems we are saying we don't need servers (and thus don't need IT Pros).  This isn't strictly the truth - which is that the server is maintained by professionals, and developers could focus on writing code.

But after working on these PowerShell for the last two weeks - actually, I'm beginning to wonder whether there will be a day we don't need Developers.

An analyst says to a Bot - I want this System A to connect to this System B and put result in this System C.  The bot arranges three connections and suggest how the parameters will be connected.  Offers to perform a trial run.  Analyst checks it and approves it.  The code goes into production.

Think about this.  Everyone needs to evolve.  IT Pros - you have a huge opportunity here to use your PowerShell skills to provide huge business value.  Developers - you should use the best tools to enable your users and do more, this is really easy to get into.

 

Tell me what you think

I really want to know what you think - if you can spend a bit of time and leave a comment below.  Where are we going as developers, where are we going as IT Pros?  What kind of PowerShell-AzureFunction are you going to build?  Does PnP need a repository for PowerShell recipes?

It's so nice to see the pieces fit together well.

Building Sandbox Solutions without Code Assembly

Sandbox Solutions are still supported in SharePoint.  But the subtle distinction is that Sandbox Code Service is switched off.  So solutions with Sandbox Code will not activate.

Activation of solutions with sandboxed code has been disabled in this site collection.

But I argue that No-Code Sandbox Solutions is still the best way to build and package assets like JavaScript, images, CSS to be deployed to SharePoint - works in SP2010, SP2013, and SPO.

So the one trick is you have to build it excluding the DLL that it compiles.

TLDR:

OK the deeper details:

By default, the sandbox solution project include assembly in package.  So when you build the solution, it includes the DLL.

When you set the project to "not include assembly in project", then the result is now "SPO-sandbox friendly"

What if I don't have the project, I just have a WSP?

You really need to know the ins and outs of the sandbox solution - what's in it, and what does it do.  But the line of thought goes

  1. Open up the WSP file with a CAB utility.  Consider IZArc - you will need to extract the contents, make your changes, then package the folder structure back into a new CAB file.
  2. Delete the assembly reference in the solution manifest.xml
  3. Repackage the WSP file and pray. 
    There are a lot of reasons why this might not work - if your package has feature or event receivers or sandbox WebParts that actually uses the code which is now missing - things will fall over (hopefully, quickly). 
  4. Please test in a separate test environment, at least a different site collection on the tenant.

delete this

When re-packaging

  • delete the assembly xml section
  • don't include the DLL again in the new CAB file.

Good luck!

 

 

Access Denied when expanding ListView Grouping

A user with partial permissions to a list gets Access Denied when expanding ListView grouping.

This is a bizarre bug.

The setup

  • Take your basic SharePoint list, a few levels of grouping and lookups.
  • List items are separated in folders in this case, which then are security trimmed to groups
  • Not every member can see list items in each set
  • When you expand the ListView webpart, you get an Access Denied error.

A quick fix

Thinking this is something to do with Postback, I ticked this option:

Life's good again.  No idea why.  

Speculate away!  Let me know in the comments if this helps you in the future.

:-)

Preparing Your Toolbox for the SharePoint Framework

In July, we were at a junction.  We had just wrapped up a new SharePoint On-Premises module with Angular v1.4 and ngOffice UI Fabric.  Our previous module was Angular v1.2 with UI Bootstrap.  We knew the SharePoint Framework was coming, and would even eventually come down to On-Premises in 2017.  Plus, at the rate JavaScript moves, we basically need to refresh our toolbox every 3 months. It was about time to do a bit of research – and so we did.

Choosing a Path

This research culminated in writing the Preparing Your Toolbox for the SharePoint Framework with Angular, Webpack and Kendo UI whitepaper, which is built around this Contract Register demo (GitHub). The technologies we picked focused primarily on what we were familiar with, but also what we knew would be supported in the SharePoint Framework.  We double checked with the examples from many professionals who have been blogging about their SharePoint Dev Kitchen experiences and against all the PnP SPFx videos.

Angular

We started with Angular and Kendo UI with Gulp, but the build process involved modularizing the code and bundling to a CDN, so we added WebPack

Finally, instead of talking to SharePoint directly, or use Kendo UI DataSource components (which also supports SharePoint REST) - I wanted us to use pnp-js-core – an optionally fluent API for talking to the REST endpoint from the Office PnP team.  

We bumped our version to Angular v1.5 because we wanted to be at the best position of being able to "deploy to production" today, but still write to the components spec that will be the norm in Angular v2.  Moreover, the SPFx-webparts will run in the SharePoint Mobile App in the future.  So without explicitly doing too much extra work - we are building toward that future where we build and it runs in the browser and on mobile.

PnP JS Core

As for PnP JS Core - the fluent API was a joy to work with, and the way batching was done is quite magical.  In v1.0.3 the library started to support server-side NodeJS as well, which means you can use the same JavaScript code to interact with your SharePoint from both the browser and the server.  Writing the same code that runs in both places is the holy grail that we always look towards.  If JavaScript can run everywhere, then the libraries we want to use should be able to run everywhere.

WebPack

As we dived deeper into the wonder that is WebPack, its magic unfolded.  In this little demo video we recorded for Contract Register you may notice how fast WebPack injects code into the browser – the app is ready before the Office 365 suite bar appears.  This is a side effect of code splitting - WebPack doesn't just merely concat and uglify the JS file. It blasts JavaScript modules into the browser like a shotgun - all at the same time. WebPack almost removes the need for Gulp in the process. Gulp tasks are still needed to start different tasks - but WebPack does the work underneath, and it does it really well.

TypeScript

We debated a lot about TypeScript.  It would have made the intelli-sense and code checking better, but we decided to leave it out. It would have been that One More Thing to learn, and the list was already getting long.  Have a look at the code we wrote for the contract-register (GitHub) and let us know if we made the right choice.

Kendo UI

I want to talk about Kendo UI as well. I hadn’t used Kendo UI before this project.  My colleague and co-author of this whitepaper, Bart Bouwhuis, is a big fan and he is constantly showing me cool features.  The whitepaper is not an advertisement for Progress (formerly Telerik), but I also think we don't really talk about Kendo UI as much as we ought to. 

My feeling is that the components are really mature – in some areas rivalling or exceeding UI Bootstrap. 

Components like Grid, Window and PDF export were easy to add.  They already support Office 365 theme, so they don't look out of place.  

Telerik supports Angular v1 and React and they just released the developer preview for Angular 2.  We ended up spending very little time making the components work for us – in most cases, we looked up the example on Telerik Docs and it just worked!  An additional blessing is we never needed to tweak a particular CSS to fix some styling problem – that was actually quite a painful issue with UI Bootstrap or ngOfficeUIFabric.

SharePoint Framework (SPFx) Developer Preview

The SPFx developer preview came out during the writing of the whitepaper.  Remember that train?  Turns out it was coming really fast.  We love how fast the SharePoint team is running.  But it means we have a few notes to add.

Firstly, the whitepaper isn't just about SPFx.  It is about SharePoint as a platform with AngularJS and WebPack, and having those pieces ready and aligned for SPFx.  It is about a stable set of core tools that works well together.  It is about a set of tools that runs today on SharePoint 2016, SharePoint 2013 and SharePoint Online.  You can already use these, without having to wait for SPFx.

Secondly, with SPFx there are even more opportunities.  We will have better support for Angular and SPA modes - currently both scenarios are not yet released.  So the story will evolve there and be more awesome.  The contract register demo can run in the SPFx webpart mode - in that case, the code to initialize the app and set up the various lists should go into the web part property panel.  So only the contributor can have access to create the lists. 

How we decided to manage this constant flux is to publish a blog update when SPFx is formally released to fill in the “gaps” – the things unknown as of the time of publishing the whitepaper. So stay tuned for such an update, likely after Microsoft Ignite.  We also have a bunch of crazy ideas listed for the Contract Register.  So if you want to get your hands dirty and have a go, we are taking pull requests!

Conclusion

The time to jump in is always now (or as soon as you can).  Here we present two months of our hardest effort to promote modern web technologies and SharePoint as a platform. 

Please download our whitepaper Preparing Your Toolbox for the SharePoint Framework with Angular, Webpack and Kendo UI, compare it to what you guys use and let us know what you like or love.

Related Resources