Skip to content

Commit 94a722b

Browse files
committed
updated provisioning article
1 parent 0836a3d commit 94a722b

6 files changed

+60
-117
lines changed
Loading
Loading
Loading
Loading
Binary file not shown.

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

Lines changed: 60 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ localization_priority: Priority
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 will 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

25-
You'll use these components to trigger the PnP provisioning code after you create the site and apply the site design.
28+
You will 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**.
34+
We are going to use authentication with a clientid and a certificate in this tutorial.
4035

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**.
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+
```
41+
Replace **contoso.onmicrosoft.com** with your tenant.
4642
47-
7. Copy the values for **Client Id** and **Client Secret** because you will need them later.
43+
Follow the steps carefully.
4844
45+
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.
46+
1. Copy the values the cmdlet returns as you will need the pfx file and the AzureAppId value later.
4947
<br/>
5048
51-
Next, trust the app, so that it has the appropriate access to your tenant:
52-
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:
56-
57-
```xml
58-
<AppPermissionRequests AllowAppOnlyPolicy="true" >
59-
<AppPermissionRequest Scope="http://sharepoint/content/tenant" Right="FullControl" />
60-
</AppPermissionRequests>
61-
```
62-
63-
1. Choose **Create**.
64-
1. To confirm that you want to trust this app, choose **Trust It**.
65-
6649
6750
## Create the Azure Queue storage
6851
@@ -171,116 +154,78 @@ Copy the following provisioning template XML to a new file and save the file as
171154

172155
1. Go to the [Azure Portal](https://portal.azure.com).
173156
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**.
176-
177-
![Screenshot of the Azure portal with the Function runtime settings screen highlighted](images/pnpprovisioning-runtime-settings.png)
178-
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)
187-
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.
189-
190-
![Screenshot of the Azure portal with the Function runtime settings screen highlighted](images/pnpprovisioning-switch-classic-experience.png)
157+
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**
158+
159+
![Screenshot of the Azure portal with the Runtime stack and Version fields hightlighted](images/pnpprovisioning-runtime-stack-selection.png)
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)
164+
1. In the dropdown menu, select **requirements.psd1** and add a new entry as follows
165+
```powershell
166+
# This file enables modules to be automatically managed by the Functions service.
167+
# See https://aka.ms/functionsmanageddependency for additional information.
168+
#
169+
@{
170+
# For latest supported version, go to 'https://www.powershellgallery.com/packages/Az'.
171+
'Az' = '5.*'
172+
# For the latest supported version, go to 'https://www.powershellgallery.com/packages/PnP.PowerShell'.
173+
'PnP.PowerShell' = '0.2.17-nightly'
174+
}
175+
```
176+
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/en-us/azure/azure-functions/functions-reference-powershell?tabs=portal#dependency-management
191177
192-
1. Create a new Azure Function **Functions** > **New function**:
178+
1. Create a new Azure Function **Functions** > **Add**:
193179
194180
![Screenshot of the Azure portal with the New function option highlighted](images/pnpprovisioning-create-function.png)
195181
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:
182+
1. Create a new Azure Store Queue Trigger function:
201183
202184
![Screenshot of the Azure portal with the new Queue Triggered function highlighted](images/pnpprovisioning-create-function-queue.png)
203185
204-
1. Name the function **ApplyPnPProvisioningTemplate**.
186+
1. Name the function **InvokePnPSiteTemplate**.
205187
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.
188+
1. Choose **Add**. A new page opens where you can modify the function.
209189
210190
> [!NOTE]
211191
> 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.
212192
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)
247193
248194
## Finish the Azure Function
249195
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.
196+
1. Go to the Function App main screen and select **Advanced Tools** in the left menu and click **Go**. A new tab will open.
197+
1. Select **PowerShell** from the **Debug Console** menu at the top.
198+
1. Navigate to **site\wwwroot\InvokePnPSiteTemplate** (or site\wwwroot\[name of your function])
199+
1. Drag and drop the earlier created **FlowDemoTemplate.xml** file onto the page. This will upload the file to the folder.
200+
1. Drag and drop the earlier generated **cert.pfx** file onto the page. This will upload the file to the folder.
201+
1. Navigate back to the function and select **Code + Test** to edit the function.
255202
1. Replace the PowerShell script with the following:
256203
257204
```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
205+
param([string] $QueueItem, $TriggerMetadata)
206+
207+
# Write out the queue message and insertion time to the information log.
208+
Write-Host "PowerShell queue trigger function processed work item: $QueueItem"
209+
Write-Host "Queue item insertion time: $($TriggerMetadata.InsertionTime)"
210+
Connect-PnPOnline -ClientId [insertyourAzureAppIdhere]] -CertificatePath D:\home\site\wwwroot\InvokePnPSiteTemplate\cert.pfx -Url $QueueItem
261211
Write-Output "Connected to site"
262-
Apply-PnPProvisioningTemplate -Path D:\home\site\wwwroot\ApplyPnPProvisioningTemplate\FlowDemoTemplate.xml
212+
Invoke-PnPSiteTemplate -Path D:\home\site\wwwroot\InvokePnPSiteTemplate\FlowDemoTemplate.xml
263213
```
264214
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.
215+
Replace **[insertyourAppIdHere]** with the value that the `Register-PnPAzureApp` cmdlet returned for AzureAppId.
269216
270217
## Create the site design
271218
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**.
219+
Open PowerShell and connect to your tenant using **Connect-PnPOnline**.
275220
276221
```powershell
277-
Connect-SPOService -Url https://[yourtenant]-admin.sharepoint.com
222+
Connect-PnPOnline -Url https://[yourtenant]-admin.sharepoint.com
278223
```
279224

280225
Now you can get the existing site designs.
281226

282227
```powershell
283-
Get-SPOSiteDesign
228+
Get-PnPSiteDesign
284229
```
285230

286231
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 +258,17 @@ To create a site design, you first need to create a site script. A site design i
313258

314259
```powershell
315260
$script = Get-Clipboard -Raw
316-
Add-SPOSiteScript -Title "Apply PnP Provisioning Template" -Content $script
317-
Get-SPOSiteScript
261+
Add-PnPSiteScript -Title "Apply PnP Site Template" -Content $script
262+
Get-PnPSiteScript
318263
```
319264

320265
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.
321266
1. Use the following command to create the site design:
322267

323268
```powershell
324-
Add-SPOSiteDesign -Title "Site with footer" -SiteScripts [Paste the ID of the Site Script here] -WebTemplate "64"
269+
Add-PnPSiteDesign -Title "Site with footer" -SiteScriptIds [Paste the ID of the Site Script here] -WebTemplate TeamSite
325270
```
326271

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-
329272
## Verify the results
330273

331274
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)