Skip to content

Commit 2f20dae

Browse files
Merge pull request SharePoint#6497 from erwinvanhunen/provisioningupdate
updated provisioning article
2 parents 0836a3d + c8a18ba commit 2f20dae

6 files changed

+61
-116
lines changed
Loading
Loading
Loading
Loading
Binary file not shown.

docs/declarative-customization/site-design-pnp-provisioning.md

Lines changed: 61 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
---
22
title: Calling the PnP provisioning engine from a site script
33
description: Build a complete SharePoint site design using the PnP provisioning engine
4-
ms.date: 07/04/2020
4+
ms.date: 11/25/2020
55
localization_priority: Priority
66
---
77

88
# Calling the PnP provisioning engine from a site script
99

10+
> [!NOTE]
11+
> This article uses a version of PnP PowerShell that is currently in pre-release and planned to GA in January 2021. As Azure Functions run PowerShell Core, you'll have to use this version of PnP PowerShell in your Azure Function. For more information about this version of PnP PowerShell see https://pnp.github.io/powershell.
12+
1013
Site designs offer a great way to standardize the look and feel of your site collections. However, you can't do some things with site designs, like add a footer to every page. You can use the PnP provisioning engine to create a template that you can use to provision an Application Customizer to a site. This Application Customizer can then update your page design, for example to register a footer on every page.
1114

1215
This article describes how to create a site design that applies a PnP provisioning template to a site. The template will add an Application Customizer to render a footer.
@@ -18,51 +21,31 @@ The steps in this article use the following components:
1821
- Azure Queue storage
1922
- Azure Functions
2023
- A SharePoint Framework (SPFx) solution
21-
- A PnP provisioning template
24+
- A PnP site template
2225
- A PnP PowerShell script
23-
- An app ID and app secret with administrative rights on your tenant
26+
- An Azure AD App Registration
2427

2528
You'll use these components to trigger the PnP provisioning code after you create the site and apply the site design.
2629

2730
[!INCLUDE [pnp-provisioning-engine](../../includes/snippets/open-source/pnp-provisioning-engine.md)]
2831

2932
## Set up app-only access to your tenant
3033

31-
To set up app-only access, you need to have two different pages on your tenant—one on the regular site, and the other on your SharePoint administration site.
32-
33-
1. Go to following URL in your tenant: `https://[yourtenant].sharepoint.com/_layouts/15/appregnew.aspx` (you can go to any site, but for now pick the root site).
34-
35-
2. Next to the **Client Id** and **Client Secret** fields, choose the **Generate** button.
36-
37-
3. Enter a title for your app, such as **Site Provisioning**.
38-
39-
4. In the **App Domain** box, enter **localhost**.
40-
41-
5. In the **Redirect URI** box, enter **https://localhost**.
42-
43-
![Create app page, showing the Client Id, Client Secret, Title, App Domain, and Redirect URI fields](images/pnpprovisioning-createapponly.png)
44-
45-
6. Choose **Create**.
46-
47-
7. Copy the values for **Client Id** and **Client Secret** because you will need them later.
48-
49-
<br/>
34+
We are going to use authentication with a clientid and a certificate in this tutorial.
5035

51-
Next, trust the app, so that it has the appropriate access to your tenant:
36+
1. Create a new self-signed certificate with PnP PowerShell on your computer:
37+
38+
```powershell
39+
Register-PnPAzureADApp -ApplicationName "PnPFlowDemo" -Tenant "contoso.onmicrosoft.com" -DeviceLogin -Out .
40+
```
5241
53-
1. Go to `https://[yourtenant]-admin.sharepoint.com/_layouts/appinv.aspx` (notice the `-admin` in the URL).
54-
1. In the **App Id** field, paste the **Client ID** that you copied, and choose **Lookup**.
55-
1. In the **Permission Request XML** field, paste the following XML:
42+
Replace **contoso.onmicrosoft.com** with your tenant.
5643
57-
```xml
58-
<AppPermissionRequests AllowAppOnlyPolicy="true" >
59-
<AppPermissionRequest Scope="http://sharepoint/content/tenant" Right="FullControl" />
60-
</AppPermissionRequests>
61-
```
44+
Follow the steps carefully.
6245
63-
1. Choose **Create**.
64-
1. To confirm that you want to trust this app, choose **Trust It**.
46+
As a result of the command a new Azure AD Application will be registered, permissions will be set correctly, and you will have provided consent to use this application in your tenant. Notice that you require write access to the Azure AD for this.
6547
48+
1. Copy the values the cmdlet returns as you will need the pfx file and the AzureAppId value later.
6649
6750
## Create the Azure Queue storage
6851
@@ -79,7 +62,6 @@ To set up the Azure Queue storage:
7962
1. Enter **pnpprovisioningqueue** for the name, or enter your own value; be sure to follow the naming standard. Make note of the queue name; you will need this value when you create the Azure Function.
8063
1. Go to **Access Keys** and note the **Storage Account Name** and the **key1 Key value**. You will need these values when you create the flow.
8164
82-
8365
## Create the flow
8466
8567
To put a message in the queue, you need to create a flow.
@@ -123,7 +105,7 @@ To put a message in the queue, you need to create a flow.
123105
1. Choose the first step in your flow ('When an HTTP request is received') and copy the URL.
124106
1. Save your flow.
125107
126-
Your flow should look like the following.
108+
Your flow should look like the following:
127109
128110
![Screenshot of a flow named 'When an HTTP request is received', showing the URL, Request body, Queue name, and Message fields](images/pnpprovisioning-flow-overview.png)
129111
@@ -137,7 +119,7 @@ $body = "{webUrl:'somesiteurl'}"
137119
Invoke-RestMethod -Uri $uri -Method Post -ContentType "application/json" -Body $body
138120
```
139121

140-
When you go to the main screen of your flow, you will see a run history. If your flow worked correctly, it will show `Succeeded`.
122+
When you go to the main screen of your flow, you'll see a run history. If your flow worked correctly, it will show `Succeeded`.
141123
Now go to the queue you just created in Azure and choose **Refresh**. You should see an entry that shows that you correctly invoked the flow.
142124

143125
## Provision the SPFx solution
@@ -171,116 +153,81 @@ Copy the following provisioning template XML to a new file and save the file as
171153

172154
1. Go to the [Azure Portal](https://portal.azure.com).
173155
1. Choose **+ Create a resource**.
174-
1. Search for **Function App** and create a new function app. In the **Storage** field, select **Use existing**, and select the storage account that you created earlier. Set the other values as required.
175-
1. Within the Function App select **Configuration** > **Function runtime settings** and change the runtime version from **~3** to **~1**.
156+
1. Search for **Function App** and create a new function app. In the **Storage** field, select **Use existing**, and select the storage account that you created earlier. Set the other values as required, but make sure to select **PowerShell Core** as the **Runtime** and select **7.0** as the **Version**
176157

177-
![Screenshot of the Azure portal with the Function runtime settings screen highlighted](images/pnpprovisioning-runtime-settings.png)
158+
![Screenshot of the Azure portal with the Runtime stack and Version fields hightlighted](images/pnpprovisioning-runtime-stack-selection.png)
178159

179-
> [!NOTE]
180-
> Function Apps based on the runtime version ~3 or ~2 only support PowerShell Core as programming language. At this moment, PnP PowerShell cmdlets can be only executed under PowerShell (and not on PowerShell Core).
181-
>
182-
> First, to make available Powershell at the level of the Function App, the runtime version has to be set to **~1**.
183-
>
184-
> Secondly, PowerShell can be only activated from the **classic experience** of the Azure Portal, by enabling the **Experimental Language Support**, at the level of the Function App.
185-
>
186-
> Read more about [Azure Functions runtime versions.](https://www.microsoft.com/download/details.aspx?id=35588)
160+
1. When created, navigate to your new Function App
161+
1. Select **App Files**
162+
163+
![Screenshot of the Function App with the App Files entry highlighted in the menu](images/pnpprovisioning-app-files.menu.png)
187164

188-
1. Temporarly switch the Azure Function App's user interface to the **classic experience** from the current experience. Select **Overview** in the left-hand navigation and select **Switch to Classic experience** as shown in the following figure.
165+
1. In the dropdown menu, select **requirements.psd1** and add a new entry as follows
189166

190-
![Screenshot of the Azure portal with the Function runtime settings screen highlighted](images/pnpprovisioning-switch-classic-experience.png)
167+
```powershell
168+
# This file enables modules to be automatically managed by the Functions service.
169+
# See https://aka.ms/functionsmanageddependency for additional information.
170+
#
171+
@{
172+
# For latest supported version, go to 'https://www.powershellgallery.com/packages/Az'.
173+
'Az' = '5.*'
174+
# For the latest supported version, go to 'https://www.powershellgallery.com/packages/PnP.PowerShell'.
175+
'PnP.PowerShell' = '0.2.17-nightly'
176+
}
177+
```
178+
Save the file. Notice, that if you do no intent to use the Azure PowerShell Cmdlets you can remove that entry from this file. The requirements.psd1 file makes sure that specific PowerShell modules will be available to all functions. At the first execution of the Azure Function these modules will be downloaded and made available. You can also use wildcard references for the version. See for more information about this file here: https://docs.microsoft.com/azure/azure-functions/functions-reference-powershell?tabs=portal#dependency-management
191179
192-
1. Create a new Azure Function **Functions** > **New function**:
180+
1. Create a new Azure Function **Functions** > **Add**:
193181
194182
![Screenshot of the Azure portal with the New function option highlighted](images/pnpprovisioning-create-function.png)
195183
196-
1. Enable **Experimental Language Support**:
197-
198-
![Screenshot of the Azure portal with the Experimental Language Support switch highlighted](images/pnpprovisioning-experimental-features.png)
199-
200-
1. Create a new Queue Triggered function based upon PowerShell:
184+
1. Create a new Azure Store Queue Trigger function:
201185
202186
![Screenshot of the Azure portal with the new Queue Triggered function highlighted](images/pnpprovisioning-create-function-queue.png)
203187
204-
1. Name the function **ApplyPnPProvisioningTemplate**.
188+
1. Name the function **InvokePnPSiteTemplate**.
205189
1. Enter the name of the queue you created earlier.
206-
1. Choose **Create**. An editor where you can enter PowerShell cmdlets will open.
207-
208-
Next, you'll upload the PnP PowerShell module so that you can use it in the Azure Function.
190+
1. Choose **Add**. A new page opens where you can modify the function.
209191
210192
> [!NOTE]
211193
> The Storage account must be in the same region as of Azure Function App, because the resources that talk to one another should be co-located in the same region. This is a requirement for Azure Functions.
212194
213-
## Upload the PnP PowerShell module for your Azure Function
214-
215-
You'll need to download the PnP PowerShell module so that you can upload it for your Azure Function.
216-
217-
1. Create a temporary folder on your computer.
218-
1. Launch PowerShell and enter the following:
219-
```powershell
220-
Save-Module -Name SharePointPnPPowerShellOnline -Path [pathtoyourfolder]
221-
```
222-
223-
The PowerShell module files will download to a folder within the folder that you created.
224-
225-
Next, upload the files so that your Azure Function can use the module.
226-
227-
1. Go to the main page of your Function App and select **Platform Features**.
228-
229-
![Screenshot of the Function App with Platform features highlighted](images/pnpprovisioning-platform-features.png)
230-
231-
1. Select **Advanced tools (Kudu)**.
232-
233-
![Screenshot of Development Tools with Advanced Tools (Kudu) highlighted](images/pnpprovisioning-select-kudu.png)
234-
235-
1. On the main Kudu page, select **Debug Console** and pick either **CMD** or **PowerShell**.
236-
1. Choose the file explorer on the upper part of the page, and go to **site\wwwroot\\[nameofyourazurefunction]**.
237-
1. Create a new folder named **modules**.
238-
239-
![Screenshot with the new folder option highlighted](images/pnpprovisioning-kudu-create-folder.png)
240-
241-
1. In the modules folder, create another folder called **SharePointPnPPowerShellOnline** and go to that folder.
242-
1. In File Explorer on your computer, go to the folder where you downloaded the PnP PowerShell module files. Open the
243-
**SharePointPnPPowerShellOnline\2.20.1711.0** folder (notice that the version number might be different).
244-
1. Drag and drop all the files from this folder into the folder in Kudu to upload them.
245-
246-
![Screenshot of the Kudu folder with 40 files added](images/pnpprovisioning-module-files-uploaded.png)
247195
248196
## Finish the Azure Function
249197
250-
1. Go back to your Azure Function and expand the files tab to the right.
251-
252-
![Screenshot of the View files tab](images/pnpprovisioning-view-files.png)
253-
254-
1. Select **Upload** and upload the provisioning template file that you created earlier.
198+
1. Go to the Function App main screen and select **Advanced Tools** in the left menu and click **Go**. A new tab will open.
199+
1. Select **PowerShell** from the **Debug Console** menu at the top.
200+
1. Navigate to **site\wwwroot\InvokePnPSiteTemplate** (or site\wwwroot\[name of your function])
201+
1. Drag and drop the earlier created **FlowDemoTemplate.xml** file onto the page. This will upload the file to the folder.
202+
1. Drag and drop the earlier generated **cert.pfx** file onto the page. This will upload the file to the folder.
203+
1. Navigate back to the function and select **Code + Test** to edit the function.
255204
1. Replace the PowerShell script with the following:
256205
257206
```powershell
258-
$in = Get-Content $triggerInput -Raw
259-
Write-Output "Incoming request for '$in'"
260-
Connect-PnPOnline -AppId $env:SPO_AppId -AppSecret $env:SPO_AppSecret -Url $in
207+
param([string] $QueueItem, $TriggerMetadata)
208+
209+
# Write out the queue message and insertion time to the information log.
210+
Write-Host "PowerShell queue trigger function processed work item: $QueueItem"
211+
Write-Host "Queue item insertion time: $($TriggerMetadata.InsertionTime)"
212+
Connect-PnPOnline -ClientId [insertyourAzureAppIdhere]] -CertificatePath D:\home\site\wwwroot\InvokePnPSiteTemplate\cert.pfx -Url $QueueItem
261213
Write-Output "Connected to site"
262-
Apply-PnPProvisioningTemplate -Path D:\home\site\wwwroot\ApplyPnPProvisioningTemplate\FlowDemoTemplate.xml
214+
Invoke-PnPSiteTemplate -Path D:\home\site\wwwroot\InvokePnPSiteTemplate\FlowDemoTemplate.xml
263215
```
264216
265-
Notice that you're using two environment variables: ```SPO_AppId```and ```SPO_AppSecret```. To set those variables, go to the main Function App page in the Azure Portal (the one with the yellow light bolt icon), select **Configuration** and add two new application settings:
266-
267-
1. ```SPO_AppId``` - Set the value to the Client ID you copied in the first step when you created your app on your tenant.
268-
2. ```SPO_AppSecret``` - Set the value to the Client Secret that you copied in the first step when you created your app on your tenant.
217+
Replace **[insertyourAppIdHere]** with the value that the `Register-PnPAzureApp` cmdlet returned for AzureAppId.
269218
270219
## Create the site design
271220
272-
Open PowerShell and make sure that you have the [SharePoint Online Management Shell](https://www.microsoft.com/download/details.aspx?id=35588) installed.
273-
274-
Connect to your tenant using **Connect-SPOService**.
221+
Open PowerShell and connect to your tenant using **Connect-PnPOnline**.
275222
276223
```powershell
277-
Connect-SPOService -Url https://[yourtenant]-admin.sharepoint.com
224+
Connect-PnPOnline -Url https://[yourtenant]-admin.sharepoint.com
278225
```
279226

280227
Now you can get the existing site designs.
281228

282229
```powershell
283-
Get-SPOSiteDesign
230+
Get-PnPSiteDesign
284231
```
285232

286233
To create a site design, you first need to create a site script. A site design is a container that refers to one or more site scripts.
@@ -313,19 +260,17 @@ To create a site design, you first need to create a site script. A site design i
313260

314261
```powershell
315262
$script = Get-Clipboard -Raw
316-
Add-SPOSiteScript -Title "Apply PnP Provisioning Template" -Content $script
317-
Get-SPOSiteScript
263+
Add-PnPSiteScript -Title "Apply PnP Site Template" -Content $script
264+
Get-PnPSiteScript
318265
```
319266

320267
1. You will see a list of one or more site scripts, including the site script you just created. Select the ID of the site script that you created and copy it to the clipboard.
321268
1. Use the following command to create the site design:
322269

323270
```powershell
324-
Add-SPOSiteDesign -Title "Site with footer" -SiteScripts [Paste the ID of the Site Script here] -WebTemplate "64"
271+
Add-PnPSiteDesign -Title "Site with footer" -SiteScriptIds [Paste the ID of the Site Script here] -WebTemplate TeamSite
325272
```
326273

327-
The **Add-SPOSiteDesign** cmdlet associates the site design with the team site. If you want to associate the design with a communication site, use the value "68".
328-
329274
## Verify the results
330275

331276
After you created your Azure Queue storage, you created the app ID for app-only access, the Azure Function, and the site design. You then triggered the Power Automate flow from the site design.

0 commit comments

Comments
 (0)