Power Automate Create sites scripts, designs, and archive for later use

 This step is part of the longer post 

Duplicate Sharepoint Online Subsite with all Site Contents and Page[s] - Power Automate

And therefor was moved to a seperated post.



3. Create sites scripts, designs, and archive

This is a 1-time process (for each design), so it should live as a manually triggered flow. Whenever you make a change, you need to run this again (and change what is relevant, if needed).
REMEMBER - that will only affect newly created subsites, not old ones!

I will show 1 Flow for 1 template, and you should create multiple, 1 for each template

This is the full flow, and I will explain each piece



Steps 1-3: 

1 - Trigger, nothing to it,
2 - Initialize Variable type of Array, to store the array of our lists and libraries to be copied
3 - Get all lists, retrieve all Custom Lists and Document Libraries Display Names, from the Template Site (in my example - "ITX2-root")



NOTICE - this is problematic in 2 ways:
First it retrieves only the Display Names, meaning that in the following scenarios you will get bad results as we need the Internal Names:
A. you changes the name
B. you created the lists/libs not in english letters (Hebrew ect.)

Second you only get 2 types - Custom Lists (100) and Document Libraries (101). If you need more lists like Calendars and other defaults you cant get them like this.

The solution for both of these problems is to use HTTP step for /_api/web/lists and then you need to smartly filter that ect., its more messy and require more work and wont be covered here.



Step 4 - Apply to Each


We need to 1st decide who is a list (type 100) and who is a library (type 101) since we need to add the "/Lists" prefix to the lists

A simple condition but we must write the expressions ourselves since the Dynamic Content doesnt show the "Type" property

So add a Condition, click "Name" for example from the get all lists step and fix it
Final value (for me) is items('Apply_to_each')?['Type']
For the right-hand side just string(100)


If Yes, its a list, lets add it to our variable with the prefix
concat('Lists/', items('Apply_to_each')?['DisplayName'])
Notice - no starting slash (/)
If you are using another api, you need to put the list actual url (i.e. internal name)




If No, its a Document Library, and we need another condition since the Display Name of the default DocLib is always changed, "Documents" for English, and whatever for your language, so you need to handle those cases and set the value to "Shared%20Documents"

So another Condition, test for the above 2 values, for our default we add 
concat('', 'Shared%20Documents') 
and for others 
concat('', items('Apply_to_each')?['DisplayName'])
(and yes you can remove the concat, but I just copy-pasted)
MAKE SURE THE CONDITION IS OR





Steps 5-7:

5 - Compose the Variable

6 - Get Site Script - its a "Send an HTTP request to SharePoint" action step, and lets detail it:

a. The site address is not important as it is saves globally
b. POST method
c. /_api/Microsoft.SharePoint.Utilities.WebTemplateExtensions.SiteScriptUtility.GetSiteScriptFromWeb
d.   Accept      +         application/json;odata=verbose
e. The body of GetSiteScriptFromWeb endpoint can be adjusted a bit if needed as documented hereMake sure you change the webUrl to your webUrl

{"webUrl":"https://bresleveloper.sharepoint.com/sites/ITX2-root",
"info":{
"IncludeBranding":true,
"IncludedLists":@{outputs('Compose')},
"IncludeRegionalSettings":true,
"IncludeSiteExternalSharingCapability":true,
"IncludeTheme":true,
"IncludeLinksToExportedItems":true}}


7 - Parse the JSON property from the results. 
outputs('Get_Site_Script')?['body']?['d']?['GetSiteScriptFromWeb']?['JSON']
Use {} for the schema since we dont need it detailed







Step 8 - Create New Site Script

This will create a SiteScript that includes all the lists and libs needed to be added and with all their columns (and formatting). You should take a look the the "Raw Output" of the "Parse JSON" action step. We will put it the the Site Design step that can include more than 1 script.

Its a "Send an HTTP request to SharePoint" action step, and lets detail it:
The site address is not important as it is saves globally
Uri is (Make Sure to change the @title value to your end)

/_api/Microsoft.SharePoint.Utilities.WebTemplateExtensions.SiteScriptUtility.CreateSiteScript(Title=@title)?@title='ITX2-Script'

Headers : 

Accept              application/json; odata.metadata=minimal
Content-Type        application/json;charset=utf-8
x-requestdigest     _spPageContextInfo.formDigestValue
ODATA-VERSION       4.0

And the body is the value parsed for the "Parse JSON" action step




Step 8 - Create New Site Design

Its a "Send an HTTP request to SharePoint" action step, and lets detail it:
The site address is not important as it is saves globally
Uri is (Make Sure to change the @title value to your end)

/_api/Microsoft.SharePoint.Utilities.WebTemplateExtensions.SiteScriptUtility.CreateSiteDesign

Headers : 

Accept              application/json; odata=verbose

And the body includes the ID of the SiteScript from the above step (Make Sute to change the Title and Description to you end)

{
  "info":{
    "Title":"ITX2-Design",
    "Description":"SubSite Example Test with lists libs files items",
    "SiteScriptIds":["@{body('Create_New_Site_Script')?['Id']}"],
    "WebTemplate":"1",
    "PreviewImageUrl": "",
    "PreviewImageAltText": "Customer tracking site design theme"
  }
}







Step 10 - Archive in helper list

This action is actually Create Item. To further inspect the Archive Helper list I created visit the main post

Here the Site Address IS important and needs to match the helper site.
Just copy-paste your titles and the script ID.
For the template id use:
body('Create_New_Site_Design')?['d']?['CreateSiteDesign']?['Id']






Best advise is to manually test it and use the correct data from the archive helper list whenver needed.
If you prefer there are examples out-there of how to make all this via O365-PowerShell


Best of Luck








Comments

Popular posts from this blog

OverTheWire[.com] Natas Walkthrough - JUST HINT, NO SPOILERS

Asp.Net Ending Response options, Response.End() vs CompleteRequest()

SOLVED The item could not be indexed successfully because the item failed in the indexing subsystem