Forum Discussion
PnP PowerShell - PnP Provisioning package (pnp) with folders
http://nickvandenheuvel.eu/2016/03/04/extract-and-apply-templates-with-office-dev-pnp-provisioning-powershell/
How are you referencing the Files?
You could create a extention in your template and use this code:
Snippet
private void CreateFolders(ClientContext context, Web web, List list, Project.Provisioning.Models.ListConfigurationListFolder[] folders) { foreach (var folder in folders) { ListItem newItem; try { // Create folder ListItemCreationInformation itemCreateInfo = new ListItemCreationInformation(); itemCreateInfo.UnderlyingObjectType = FileSystemObjectType.Folder; itemCreateInfo.LeafName = folder.Title; newItem = list.AddItem(itemCreateInfo); newItem["Title"] = folder.Title; newItem.Update(); context.ExecuteQueryRetry(); } catch (Exception e) { TraceHelper.WriteInformationToListener("LogFile", $"Couldn't create folder: {folder.Title}."); continue; } if (folder.ObjectSecurity != null) { // Set item security var securitySettings = folder.ObjectSecurity.BreakRoleInheritance; if (securitySettings.RoleAssignment.Length == 0) continue; try { var groups = context.LoadQuery(context.Web.SiteGroups.Include(g => g.LoginName)); var webRoleDefinitions = context.LoadQuery(context.Web.RoleDefinitions); context.ExecuteQueryRetry(); newItem.BreakRoleInheritance(securitySettings.CopyRoleAssignments, securitySettings.ClearSubscopes); foreach (var roleAssignment in securitySettings.RoleAssignment) { Principal principal = groups.FirstOrDefault(g => g.LoginName == roleAssignment.Principal); if (principal == null) { principal = context.Web.EnsureUser(roleAssignment.Principal); } var roleDefinitionBindingCollection = new RoleDefinitionBindingCollection(context); var roleDefinition = webRoleDefinitions.FirstOrDefault(r => r.Name == roleAssignment.RoleDefinition); if (roleDefinition != null) { roleDefinitionBindingCollection.Add(roleDefinition); } newItem.RoleAssignments.Add(principal, roleDefinitionBindingCollection); } context.ExecuteQueryRetry(); } catch (Exception e) { TraceHelper.WriteInformationToListener("LogFile", "Error occured when setting itemlevel security on folder."); continue; } } } }
- Niclas CarlssonFeb 20, 2017Brass Contributor
Yep I guess that I have to look at a custom extension. Too bad as it would have been nice if the Convert-PnPFolderToProvisioningTemplate command had packaged the files and folders in the same pnp package.
/Niclas
- Nigel PriceFeb 19, 2017Iron Contributor
Hi Paul
What would the provisioning Template entries look like to support the folder hierarchy?
Regards
Nigel
- DeletedFeb 20, 2017
hi Nigel,
in my code i did a big one this is a extract of the template:
<def:ListConfiguration xmlns:def="http://tempuri.org/ListConfiguration"> <def:SiteUrl>{parameter:SiteCollectionUrl}</def:SiteUrl> <def:Lists> <def:List Url="COM"> <def:Folders> <def:Folder Title="Estimates"> <def:ObjectSecurity> <def:BreakRoleInheritance ClearSubscopes="false" CopyRoleAssignments="true"> <def:RoleAssignment Principal="Estimators" RoleDefinition="ContributeWithoutDelete"/> </def:BreakRoleInheritance> </def:ObjectSecurity> </def:Folder> </def:Folders> </def:List> </def:Lists> </def:ListConfiguration>
- Nigel PriceFeb 22, 2017Iron Contributor
Hi Paul
@ErwinVanHunen's Blog says this is the call you make for the extension ->
public void ProcessRequest(ClientContext ctx, ProvisioningTemplate template, string configurationData)
Your code has this ->
private void CreateFolders(ClientContext context, Web web, List list, Project.Provisioning.Models.ListConfigurationListFolder[] folders)
So I presume I have to convert between the two.
I can get web from the clientcontext but for the list I need to have the list name. Where do I get that from ?
Thanks
Nigel