SharePoint Patterns and Practices (PnP) for PowerShell are a set of modules and commands that help to automate certain processes that are regularly part of most consulting engagements such as turning off features or creating new site collections. The Patterns and Practices commands don’t do a lot of new things but combine existing code into the compiled commands. This reduces the need to write many longer scripts to accomplish the same tasks so the PnP module helps get these tasks done in a more efficient manner.

I have recently started blogging so please bear with me if this seems mildly…unpolished. I have been using PowerShell for years now but I would not say I am a PoSH ninja, maybe a grasshopper. I recently found the SharePoint PowerShell Patterns and Practices module and am pretty pleased with the options, which is what I want to talk about in this blog.

What are we trying to accomplish: The intent is to create and use a template to provision new site collections with in an automated manner and apply the template to the provisioned site collection. This template should include the branding but also the workflows, lists and anything needed to reproduce the site collection.

To get started with the Patterns and Practices module for SharePoint Online run the following command in ISE:

Install-Module SharePointPnPPowerShellOnline

If you get the following error:

PackageManagement\Install-Package : The version ‘x.x.x.x’ of the module ‘SharePointPnPPowerShellOnline’ being installed is not catalog signed.

Then run the following command:


Install-Module SharePointPnPPowerShellOnline -SkipPublisherCheck -AllowClobber

Now that we have the Module installed you will want to update it on a regular basis:


Update-Module SharePointPnPPowerShell* 

Updates for the module come out monthly. If you go to the home page at Github for this you will see a link to see the list of commands available. My intent is to show how to provision a new site collection and apply a template to it. In the normal course of events SharePoint Templates are applied at creation and they cannot be changed, and while this is still true for the base web template, it does not mean you cannot pull your configurations to the OOB template down and apply them in a automagical way. Follow me now as I lead you down the rosy path…

The very first thing we need to do is to set up our user credentials in Windows Credential Manager. Seems a little odd you say? After you use it this way you won’t think so. If you do not do this, then you will be inputting credentials every time you run these commands, so it saves you time and that is something all PoSH writers want, correct?

credmanager

Once you click on Add a generic credential you will see:

creds

In the internet or network address put the admin site for your tenant such as https://contosos-admin.sharepoint.com and fill out the username and password you use to login. Do the same for the base site such as https://contoso.sharepoint.com . Just do it and bear with me, you will be glad you did.

Full Script:
$localFiles = “C:\Temp\Contoso”
$newsite = “O365ProjectAcme”
$siteTitle = “Acme Site”
$siteOwner = “wcoyote@contoso.onmicrosoft.com”
$addOwner = “bbunny@ltunes.com”
$addMember = “dduck@ltunes.com”
$storageQuota = “1000” #in Mb
$initialConnect = “https://contoso.sharepoint.com/sites/O365Projects”
$baseUrl = “https://contoso.sharepoint.com/sites/”
$ProjectTemplate = “Projecttemplate.pnp”
$sitelogo = “/sites/” + $newsite + “/SiteAssets/” + “datsallfolks.gif”
$fullUrl = $baseUrl + $newsite
cd $localFiles
$iconnect = “https://contoso.sharepoint.com/sites/O365BiglyWork”
Connect-PnPOnline -Url $iconnect
Get-PnPProvisioningTemplate -Out Projecttemplate.pnp -PersistBrandingFiles -Force -Verbose
Connect-PnPOnline -Url $initialConnect
New-PnPTenantSite -Title $siteTitle -Url /sites/$newsite -Owner $siteOwner -TimeZone 10 -Template STS#0 -ResourceQuota 1 -StorageQuota $storageQuota -Force -Wait
Connect-PnPOnline -Url $fullUrl
Enable-PnPResponsiveUI
Apply-PnPProvisioningTemplate -Path $ProjectTemplate -ClearNavigation
Ensure-PnPFolder -SiteRelativePath “/SiteAssets/”
Add-PnPFile -Path C:\Temp\Contoso\datsallfolks.gif -Folder “/SiteAssets/”
Set-PnPWeb -SiteLogoUrl $sitelogo
$ownersGroup = Get-PnPGroup -AssociatedOwnerGroup | select Title
if($addOwner){
Add-PnPUserToGroup -LoginName $addOwner -Identity $ownersGroup.Title
}

Now back to ISE.  We put in the variables for the script:

$localFiles = “C:\Temp\Contoso”

$newsite = “O365ProjectAcme”

$siteTitle = “Acme Site”

$siteOwner = “wcoyote@contoso.onmicrosoft.com”

$addOwner = “bbunny@ltunes.com”

$addMember = “dduck@ltunes.com”

$storageQuota = “1000” #in Mb

$initialConnect = “https://contoso.sharepoint.com/sites/O365Projects”

$baseUrl = “https://contoso.sharepoint.com/sites/”

$ProjectTemplate = “Projecttemplate.pnp”

$sitelogo = “/sites/” + $newsite + “/SiteAssets/” + “datsallfolks.gif”

$fullUrl = $baseUrl + $newsite

cd $localFiles

Now we want to get a template of the configured site collection we have been working on all day. First we connect to the site:

$iconnect = “https://contoso.sharepoint.com/sites/O365BiglyWork”

Connect-PnPOnline -Url $iconnect

Then we do a classic CD into the directory we want to store the files in. Note: Does not work well in ODFB, what with that whole sync thing happening.

PS C:\Temp\contoso> Get-PnPProvisioningTemplate -Out Projecttemplate.pnp -PersistBrandingFiles -Force -Verbose

The next thing we need to do from a scripting point of view is to connect to an existing site, once we are connected the script then has our context. If we need to connect to the admin site with that context we can without explicitly connecting again. Run the following command:

Connect-PnPOnline -Url $initialConnect

Once you run the command it may not seem like anything happened, ahh but it did. To prove that run the following command:

Get-PnPGroup

You should then have a list of the SharePoint groups in the site collection, without having to provide credentials, nice, yes?

When we create a site collection we choose the template, so lets start with the single most used template; Team site. To create a Team Site Collection use the following command:

New-PnPTenantSite -Title $siteTitle -Url /sites/$newsite -Owner $siteOwner -TimeZone 10 -Template STS#0 -ResourceQuota 1 -StorageQuota $storageQuota -Force -Wait

This command creates the new site collection using the STS#0 template. You will find that because we added the -wait parameter the script will not continue until the site collection is completed.  Next we will do another connect to change the context:

Connect-PnPOnline -Url $fullUrl

This will put us in the right site to continue the script. In my mind I always want a responsive site in case I go all mobile on it from my tablet. To do this is pretty simple, since we already have the context we just run the following command:

Enable-PnPResponsiveUI

That’s it. The only other piece that is required for subsites is to disable the “Mobile Browser View” feature. The reason for this is that feature conflicts with the responsive UI. From the PNP documentation “Will upload a CSS file, a JavaScript file and adds a custom action to the root web of the current site collection, enabling the responsive UI on the site collection. The CSS and JavaScript files are located in the style library, in a folder called SP.Responsive.UI”

Now we will apply the template that we made earlier to our shiny new site. Notice that I am still in the same directory as the output of the template creation.

PS C:\Temp\contoso> Apply-PnPProvisioningTemplate -Path $ProjectTemplate -ClearNavigation

Now, between waiting on the site collection to be created and waiting on the template to apply, being a true IT guy/gal you will want to go out and get a cup of java and maybe a donut as well. Hang out at the water fountain, tell a few lies about the javascript you wrote and when you get back it MIGHT be done.

The key here is that when you configure your initial site collection, add some pages, some web parts then add a couple of workflows, maybe throw a theme on the site collection, once you’ve done all that you feel pretty good and would like to use it over and over again. Using this technique, you can.

In this application I decided that I should add a logo file to the site after the template was applied. The first part of that is to make sure that the folder is there and create it if it is not:

PS C:\Temp\contoso> Ensure-PnPFolder -SiteRelativePath “/SiteAssets/”
Once that comes back OK, I do the following command to upload my logo:

PS C:\Temp\contoso> Add-PnPFile -Path C:\Temp\Contoso\datsallfolks.gif -Folder “/SiteAssets/”
Then, I need to set the logo as the site logo since just uploading it doesn’t do that.

PS C:\Temp\contoso> Set-PnPWeb -SiteLogoUrl $sitelogo
Next I want to add an owner to the site collection. I get the owners group and select the title with the following line:

PS C:\Temp\contoso> $ownersGroup = Get-PnPGroup -AssociatedOwnerGroup | select Title
I then make sure that my AddOwner variable has a value and add the user to the owners group:

if($addOwner){

Add-PnPUserToGroup -LoginName $addOwner -Identity $ownersGroup.Title

}

So you can see that the PnP is very handy for the SharePoint admins out there. And yes, I did say “SharePoint Admins” not “SharePoint Online Admins”, they have given you on Premise folk a little love too:

SharePoint Version Command to install
SharePoint Online Install-Module SharePointPnPPowerShellOnline
SharePoint 2016 Install-Module SharePointPnPPowerShell2016
SharePoint 2013 Install-Module SharePointPnPPowerShell2013

 

That being said, the title of this blog is PnP Posh Hits the high notes. So, there is at least one sour note that perked up along the way. Please check to make sure all your calculated fields have the field names in the proper brackets or the commands will throw an error. And while the errors are helpful, sort of, they do not say where the offending field is so if your site collection is large with lots of customization you may have to search a bit.

I have to say, I am most happy about the ability to migrate SharePoint Designer workflows between site collections with this and overall the song of SharePoint is a happy tune these days…

Live Long and Prosper

DM

Hits: 691