Reputation: 35
I have a code that copies a folder structure from 1 site to another, the question is how to copy folder access if the groups have the same name in 2 sites.
Group Title: PTO
Group Title: IK
Group Title: ITN
Group Title: DESIGNER
Group Title: CUSTOMER
Group Title: CONTRACTOR\
using PnP.Framework;
using Microsoft.SharePoint.Client;
using Folder = Microsoft.SharePoint.Client.Folder;
public void CopyFolderStructureBetweenSites(string siteUrl)
{
string sourceSiteUrl = "MYSITEURL";
string sourceLibraryName = "Documents";
string targetLibraryName = "Documents";
string folderName = "General";
using ClientContext sourceContext = GetSharePointContext(_clientId, _certPath, _certPass, _tenantName,
sourceSiteUrl);
using ClientContext targetContext = GetSharePointContext(_clientId, _certPath, _certPass, _tenantName,
siteUrl);
// Getting the folder to copy from the source library
Folder sourceFolder = GetFolder(sourceContext, sourceLibraryName, folderName);
if (sourceFolder != null)
{
// Check if the target library exists, if not, create it
List targetLibrary = EnsureTargetLibrary(targetContext, targetLibraryName);
CopyFolder(sourceContext, targetContext, sourceFolder, targetLibrary);
Console.WriteLine("Done.");
}
else
{
Console.WriteLine("Unluck.");
}
}
private void CopyFolder(ClientContext sourceContext, ClientContext targetContext, Folder sourceFolder, List targetLibrary)
{
targetContext.Load(targetLibrary.RootFolder);
targetContext.ExecuteQuery();
var folderUrl = targetLibrary.RootFolder.ServerRelativeUrl + "/" + sourceFolder.Name;
Folder newFolder = targetLibrary.RootFolder.Folders.Add(sourceFolder.Name);
targetContext.ExecuteQuery();
CopyFolderRecursive(sourceContext, targetContext, sourceFolder, newFolder);
}
private void CopyFolderRecursive(ClientContext sourceContext, ClientContext targetContext, Folder sourceFolder, Folder targetFolder)
{
sourceContext.Load(sourceFolder.Files);
sourceContext.Load(sourceFolder.Folders);
sourceContext.ExecuteQuery();
foreach (Folder subFolder in sourceFolder.Folders)
{
var newTargetFolder = targetFolder.Folders.Add(subFolder.Name);
targetContext.ExecuteQuery();
CopyFolderRecursive(sourceContext, targetContext, subFolder, newTargetFolder);
}
}
Upvotes: 0
Views: 179
Reputation: 35
In general, with a little help from AI, I solved the problem.
CopyFolderPermissions handles copying permissions from one folder to another. It does this by iterating through all the role assignments in the source folder, copying those assignments to the destination folder. This involves getting the group (if it exists), dropping all relevant roles (except for limited access), and then adding those roles to the target folder.
CopyFolder deals with copying the contents of a folder from the source folder to the target folder. This includes creating subfolders and calling the CopyFolderPermissions function to copy permissions. The function recursively processes all subfolders and copies their contents and permissions.
private void CopyFolderPermissions(ClientContext sourceCtx, ClientContext targetCtx, Folder sourceFolder, Folder targetFolder, string sourceDisplayName, string targetDisplayName)
{
var roleAssignments = sourceFolder.ListItemAllFields.RoleAssignments;
sourceCtx.Load(roleAssignments);
sourceCtx.ExecuteQuery();
foreach (var assignment in roleAssignments)
{
var roleDefinitionBindings = assignment.RoleDefinitionBindings;
sourceCtx.Load(assignment.Member);
sourceCtx.Load(roleDefinitionBindings);
sourceCtx.ExecuteQuery();
// Replace the display name in the group's login name
var groupName = assignment.Member.LoginName.Replace(sourceDisplayName, targetDisplayName);
Group principal = null;
try
{
principal = targetCtx.Web.SiteGroups.GetByName(groupName);
targetCtx.Load(principal);
targetCtx.ExecuteQuery();
}
catch (ServerException)
{
// Do nothing, Group doesn't exist.
}
if(principal != null)
{
var newRoleDefBindings = new RoleDefinitionBindingCollection(targetCtx);
foreach (var roleDef in roleDefinitionBindings)
{
// exclude Limited Access level
if(roleDef.RoleTypeKind != RoleType.Guest)
{
newRoleDefBindings.Add(targetCtx.Web.RoleDefinitions.GetById(roleDef.Id));
}
}
// Stop inheriting permissions
targetFolder.ListItemAllFields.BreakRoleInheritance(false, false);
// Add new role assignments
targetFolder.ListItemAllFields.RoleAssignments.Add(principal, newRoleDefBindings);
}
}
targetCtx.ExecuteQuery();
}
private void CopyFolder(ClientContext sourceCtx, ClientContext targetCtx, Folder sourceFolder, Folder targetFolder, string sourceDisplayName, string targetDisplayName)
{
Folder newFolder;
if (targetFolder.FolderExists(sourceFolder.Name))
{
newFolder = targetFolder.Folders.GetByUrl(sourceFolder.Name);
}
else
{
newFolder = targetFolder;
}
targetCtx.Load(newFolder);
targetCtx.ExecuteQuery();
CopyFolderPermissions(sourceCtx, targetCtx, sourceFolder, newFolder, sourceDisplayName, targetDisplayName);
sourceCtx.Load(sourceFolder.Folders);
sourceCtx.ExecuteQuery();
foreach (Folder subFolder in sourceFolder.Folders)
{
// We need to create a subfolder in the newFolder for each subfolder in the sourceFolder
Folder targetSubFolder;
if (!newFolder.FolderExists(subFolder.Name))
{
targetSubFolder = newFolder.Folders.Add(subFolder.Name);
targetCtx.ExecuteQuery();
}
else
{
targetSubFolder = newFolder.Folders.GetByUrl(subFolder.Name);
}
CopyFolder(sourceCtx, targetCtx, subFolder, targetSubFolder, sourceDisplayName, targetDisplayName);
}
}
Upvotes: 0