How to copy the folder structure and permissions with in the same library
-
07-02-2021 - |
Frage
I have a document libray with structure like given below: FolderA->Subfolder1->item1 Subfolder2-->item2 They have folder level permissions . now i want to create the same folder structure and permissions with different Folder Parent name for example:
Once we copy the folder structure should be FOLDER B-->Subfolder1->item1 Subfolder2-->item2
This is for sharepointonline CSOM powershell.
I was able to copy the folder structure but unable to get permissions is anything missing
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.dll"
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.Taxonomy.dll"
Function Copy-SPOFolder([String]$SiteURL, [String]$SourceFolderURL, [String]$TargetFolderURL)
{
$Host.Runspace.ThreadOptions = "ReuseThread"
Try{
#Copy the Folder
$MoveCopyOpt = New-Object Microsoft.SharePoint.Client.MoveCopyOptions
[Microsoft.SharePoint.Client.MoveCopyUtil]::CopyFolder($ctx, $SourceFolderURL, $TargetFolderURL, $MoveCopyOpt)
$ctx.ExecuteQuery()
Write-host -f Green "Folder Copied Successfully!" }
Catch {
write-host -f Red "Error Copying the Folder!" $_.Exception.Message
}
}
function Connect-SPO()
{
param ([Parameter(Mandatory=$true,Position=1)][string]$Username,[Parameter(Mandatory=$true,Position=2)][string]$Url,[Parameter(Mandatory=$true,Position=3)]$AdminPassword)
$global:ctx=New-Object Microsoft.SharePoint.Client.ClientContext($Url)
$ctx.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Username, $AdminPassword)
$ctx.Load($ctx.Web)
$ctx.ExecuteQuery()
}
#Function to Get Folder Permissions
Function Get-SPOFolderPermission([String]$SiteURL, [String]$FolderRelativeURL)
{
$Host.Runspace.ThreadOptions = "ReuseThread"
Try{
#Get the Folder
$Folder = $ctx.Web.GetFolderByServerRelativeUrl($FolderRelativeURL)
$ctx.Load($Folder)
$ctx.ExecuteQuery()
#Get permissions assigned to the Folder
$RoleAssignments = $Folder.ListItemAllFields.RoleAssignments
$ctx.Load($RoleAssignments)
$ctx.ExecuteQuery()
#Loop through each permission assigned and extract details
$PermissionCollection = @()
Foreach($RoleAssignment in $RoleAssignments)
{
$ctx.Load($RoleAssignment.Member)
$ctx.executeQuery()
#Get the User Type
$PermissionType = $RoleAssignment.Member.PrincipalType
#Get the Permission Levels assigned
$ctx.Load($RoleAssignment.RoleDefinitionBindings)
$ctx.ExecuteQuery()
$PermissionLevels = ($RoleAssignment.RoleDefinitionBindings | Select -ExpandProperty Name) -join ","
#Get the User/Group Name
$Name = $RoleAssignment.Member.Title # $RoleAssignment.Member.LoginName
#Add the Data to Object
$Permissions = New-Object PSObject
$Permissions | Add-Member NoteProperty Name($Name)
$Permissions | Add-Member NoteProperty Type($PermissionType)
$Permissions | Add-Member NoteProperty PermissionLevels($PermissionLevels)
$PermissionCollection += $Permissions
}
Return $PermissionCollection
}
Catch {
write-host -f Red "Error Getting Folder Permissions!" $_.Exception.Message
}
}
#variables
$admin="santosh.sandy@micrososft.sharepoint.com"
$pass= ConvertTo-SecureString "TSDTD" -AsPlainText -Force
$SiteURL="https://sandy.sharepoint.com/sites/hgs_demo/"
$LibraryName="FolderTest";
$SrcFolderName="RootLibrary"
$NewFolderName="RootLibrary1"
$global:ctx
Try {
Connect-SPO -Username $admin -Url $SiteURL -AdminPassword $pass
$Library=$ctx.Web.Lists.GetByTitle($LibraryName);
$Folders = $Library.RootFolder.Folders
$ctx.Load($Library);
$ctx.Load($Folders)
$ctx.ExecuteQuery()
#Get existing folder names
$FolderNames = $Folders | Select -ExpandProperty Name
if($FolderNames -contains $NewFolderName)
{
write-host "Folder Exists Already!" -ForegroundColor Yellow
}
else{
$SourceFolderURL= $SiteURL + $LibraryName +"/" + $SrcFolderName
$TargetFolderURL= $SiteURL + $LibraryName +"/" + $NewFolderName
Copy-SPOFolder $SiteURL $SourceFolderURL $TargetFolderURL
$ctx.Load($Library);
$ctx.Load($Folders)
$ctx.ExecuteQuery()
$FolderNames = $Folders | Select -ExpandProperty Name
if($FolderNames -contains $NewFolderName)
{
$FolderRelativeURL= "/sites/hgs_demo/"+ $LibraryName +"/" + $NewFolderName
# write-host "Folder Exists Already!" -ForegroundColor Yellow
$cFolder = $ctx.Web.GetFolderByServerRelativeUrl($FolderRelativeURL)
$ctx.Load($cFolder)
$ctx.ExecuteQuery()
#Break Permission inheritence - Remove all existing list permissions & keep Item level permissions
$cFolder.ListItemAllFields.BreakRoleInheritance($False,$True)
$ctx.ExecuteQuery()
Write-host -f Yellow "Folder's Permission inheritance broken..."
$copyfolderRetaltiveurl= "/sites/hgs_demo/"+ $LibraryName +"/" + $SrcFolderName
$PermissionCopy= Get-SPOFolderPermission $SiteURL $copyfolderRetaltiveurl
foreach($Permission in $PermissionCopy)
{
Write-Host $Permission.Name +".." $Permission.Type +"..." $Permission.PermissionLevels
if($Permission.Type -eq "User")
{
$UserAccount =$Permission.Name
}
else{
$GroupName = $Permission.Name
}
#Get the SharePoint Group & User
$Group =$ctx.Web.SiteGroups.GetByName($GroupName)
$User = $ctx.Web.EnsureUser($UserAccount)
$ctx.load($Group)
$ctx.load($User)
$ctx.ExecuteQuery()
#Grant permission
#Get the role required
$Role = $ctx.Web.RoleDefinitions.GetByName($Permission.PermissionLevels)
$RoleDB = New-Object Microsoft.SharePoint.Client.RoleDefinitionBindingCollection($ctx)
$RoleDB.Add($Role)
#Assign permissions
$GroupPermissions = $cFolder.ListItemAllFields.RoleAssignments.Add($Group,$RoleDB)
$UserPermissions = $cFolder.ListItemAllFields.RoleAssignments.Add($User,$RoleDB)
$cFolder.Update()
$ctx.ExecuteQuery()
Write-host "Permission Granted Successfully!" -ForegroundColor Green
}#end of for each loop
}
}
}
Catch {
write-host -f Red "Error Granting permission to Folder!" $_.Exception.Message
}
Lösung
I was able to achieve this below is the code.Can any one help me in making my code small.
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.dll"
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.Taxonomy.dll"
########################################
#### Connection Funtions #############
########################################
function Connect-SPO()
{
param ([Parameter(Mandatory=$true,Position=1)][string]$Username,[Parameter(Mandatory=$true,Position=2)][string]$Url,[Parameter(Mandatory=$true,Position=3)]$AdminPassword)
$global:ctx=New-Object Microsoft.SharePoint.Client.ClientContext($Url)
$ctx.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Username, $AdminPassword)
$ctx.Load($ctx.Web)
$ctx.ExecuteQuery()
}
########################################
#### Recurse Function #################
########################################
function Recurse($Folder)
{
$Host.Runspace.ThreadOptions = "ReuseThread"
$folderName = $Folder.Name
$folderItemCount = $folder.ItemCount
Write-Host "Folder Name ->'$folderName'"
Write-Host "Number of List Items->'$folderItemCount'"
if($Folder.name -eq $SrcFolderName)
{
$Rootfolderurl= $Folder.ServerRelativeUrl
$NewRootFolder=$RootfolderURl.Replace($SrcFolderName,$NewFolderName)
Write-Host $Rootfolderurl -ForegroundColor Magenta
Write-Host $NewRootFolder -ForegroundColor Magenta
###########################
#Create the new Root Folder
##########################
###Create-Folder -LibraryName $LibraryName -FolderName $NewFolderName -RootPermissionCol $RootPermissionCopy
#Create the Folder
$CreateNewFolder=$ctx.Web.Folders.Add($NewRootFolder)
$ctx.ExecuteQuery()
Write-Host "Folder Created"
#############################
###Get Security on RootFolder
#############################
$RootPermissionCopy= Get-SPOFolderPermission -FolderRelativeURL $Rootfolderurl
#############################
###Break Inheritence on New Root Folder
#############################
$cFolder = $ctx.Web.GetFolderByServerRelativeUrl($NewRootFolder)
$ctx.Load($cFolder)
$ctx.ExecuteQuery()
#Break Permission inheritence - Remove all existing list permissions & keep Item level permissions
$cFolder.ListItemAllFields.BreakRoleInheritance($False,$True)
$ctx.ExecuteQuery()
foreach($Permission in $RootPermissionCopy)
{
Write-Host "Name " $Permission.Name
Write-Host "Type " $Permission.Type
Write-Host "Permission Levels" $Permission.PermissionLevels
#Check and Skip if Permission are only "Limited Access"
If ($Permission.PermissionLevels -eq "Limited Access") {
Write-Host "Skipping because there is only Limited Access"
Write-Host ""
}
Else {
if($Permission.Type -eq "User"){
$PermLevelArray=$Permission.PermissionLevels -split ","
$UserAccount =$Permission.Name
$User = $ctx.Web.EnsureUser($UserAccount)
$ctx.load($User)
$ctx.ExecuteQuery()
Foreach($PermLevel in $PermLevelArray){
write-host $PermLevel
if($PermLevel -eq "Limited Access") {
Write-Host "Skipping Limited Access"
}
Else {
$Role = $ctx.Web.RoleDefinitions.GetByName($PermLevel)
$RoleDB = New-Object Microsoft.SharePoint.Client.RoleDefinitionBindingCollection($ctx)
$RoleDB.Add($Role)
$UserPermissions = $cFolder.ListItemAllFields.RoleAssignments.Add($User,$RoleDB)
Write-Host "Applied " $PermLevel
$cFolder.Update()
try {
$ctx.ExecuteQuery()
}
Catch {
Write-host "User cannot be found"
}
}
}
}
else{
Write-host $Permission.Name
$PermLevelArray=$Permission.PermissionLevels -split ","
$GroupName = $Permission.Name
$Group =$ctx.Web.SiteGroups.GetByName($GroupName)
$ctx.load($Group)
$ctx.ExecuteQuery()
Foreach($PermLevel in $PermLevelArray){
write-host $PermLevel
if($PermLevel -eq "Limited Access") {
Write-Host "Skipping Limited Access"
}
Else {
$Role = $ctx.Web.RoleDefinitions.GetByName($PermLevel)
$RoleDB = New-Object Microsoft.SharePoint.Client.RoleDefinitionBindingCollection($ctx)
$RoleDB.Add($Role)
$GroupPermissions = $cFolder.ListItemAllFields.RoleAssignments.Add($Group,$RoleDB)
Write-Host "Applied " $PermLevel
$cFolder.Update()
Try {
$ctx.ExecuteQuery()
}
Catch {
Write-host "Group Cannot be Found"
}
}
}
}
}
}
Write-Host "Permissions Retrieved"
}
Else
{
################################
##Create New SubFolder
################################
Write-Host "Copy this folder as a none root folder!!" -ForegroundColor Cyan
#Get Relative Url of the Folder to Copy
$CurrentFolderUrl= $Folder.ServerRelativeUrl
Write-Host $CurrentFolderUrl -ForegroundColor Green
#Create Url of the Folder to Create based on the Current Folder - Replace Folder Path
$FolderToAdd = $CurrentFolderUrl.Replace($SrcFolderName,$NewFolderName)
Write-Host "Add===> "$FolderToAdd -ForegroundColor Cyan
#Create the Folder
$CreateNewFolder=$ctx.Web.Folders.Add($FolderToAdd)
$ctx.ExecuteQuery()
Write-Host "Folder Created"
#############################
###Get Security on Current Folder
#############################
$CurrentPermissionCopy= Get-SPOFolderPermission -FolderRelativeURL $CurrentFolderUrl
#############################
###Break Inheritence on New Root Folder
#############################
$cFolder = $ctx.Web.GetFolderByServerRelativeUrl($FolderToAdd)
$ctx.Load($cFolder)
$ctx.ExecuteQuery()
#Break Permission inheritence - Remove all existing list permissions & keep Item level permissions
$cFolder.ListItemAllFields.BreakRoleInheritance($False,$True)
$ctx.ExecuteQuery()
foreach($Permission in $CurrentPermissionCopy)
{
Write-Host "Name " $Permission.Name
Write-Host "Type " $Permission.Type
Write-Host "Permission Levels" $Permission.PermissionLevels
#Check and Skip if Permission are only "Limited Access"
If ($Permission.PermissionLevels -eq "Limited Access") {
Write-Host "Skipping because there is only Limited Access"
Write-Host ""
}
Else {
if($Permission.Type -eq "User"){
$PermLevelArray=$Permission.PermissionLevels -split ","
$UserAccount =$Permission.Name
$User = $ctx.Web.EnsureUser($UserAccount)
$ctx.load($User)
$ctx.ExecuteQuery()
Foreach($PermLevel in $PermLevelArray){
write-host $PermLevel
if($PermLevel -eq "Limited Access") {
Write-Host "Skipping Limited Access"
}
Else {
$Role = $ctx.Web.RoleDefinitions.GetByName($PermLevel)
$RoleDB = New-Object Microsoft.SharePoint.Client.RoleDefinitionBindingCollection($ctx)
$RoleDB.Add($Role)
$UserPermissions = $cFolder.ListItemAllFields.RoleAssignments.Add($User,$RoleDB)
Write-Host "Applied " $PermLevel
$cFolder.Update()
try {
$ctx.ExecuteQuery()
}
Catch {
Write-host "User cannot be found"
}
}
}
}
else{
Write-host $Permission.Name
$PermLevelArray=$Permission.PermissionLevels -split ","
$GroupName = $Permission.Name
$Group =$ctx.Web.SiteGroups.GetByName($GroupName)
$ctx.load($Group)
$ctx.ExecuteQuery()
Foreach($PermLevel in $PermLevelArray){
write-host $PermLevel
if($PermLevel -eq "Limited Access") {
Write-Host "Skipping Limited Access"
}
Else {
$Role = $ctx.Web.RoleDefinitions.GetByName($PermLevel)
$RoleDB = New-Object Microsoft.SharePoint.Client.RoleDefinitionBindingCollection($ctx)
$RoleDB.Add($Role)
$GroupPermissions = $cFolder.ListItemAllFields.RoleAssignments.Add($Group,$RoleDB)
Write-Host "Applied " $PermLevel
$cFolder.Update()
Try {
$ctx.ExecuteQuery()
}
Catch {
Write-host "Group Cannot be Found"
}
}
}
}
}
}
}
#Write-Host $folder.ListItemAllFields.HasUniqueRoleAssignments
$thisFolder = $ctx.Web.GetFolderByServerRelativeUrl($Folder.ServerRelativeUrl)
$ctx.Load($thisFolder)
$ctx.Load($thisFolder.Folders)
$ctx.ExecuteQuery()
foreach($subfolder in $thisFolder.Folders)
{
Write-Host $subfolder.ServerRelativeUrl -ForegroundColor Gray
Recurse $subfolder
}
}
##########################################
#### Function to Get Folder Permissions ##
##########################################
Function Check-SPOFolderExists()
{
param
( [Parameter(Mandatory=$true)] [string] $FolderRelativeURL)
$Host.Runspace.ThreadOptions = "ReuseThread"
$checkfolderExists="False"
Try {
#Check Folder Exists
$checkfolder= $ctx.web.GetFolderByServerRelativeUrl($FolderRelativeURL)
$ctx.Load($Folder)
$ctx.ExecuteQuery()
$checkfolderExists="True";
#Write-host -f Green "Folder Exists!"
}
catch{
Write-host -f Yellow "Folder Doesn't Exist!"
#Write-Host "Error in Check-SPoFolder Function with Message" $_.Exception.Message
}
return $checkfolderExists
}
##########################################
#### Function to Get Folder Permissions ##
##########################################
Function Get-SPOFolderPermission([String]$FolderRelativeURL)
{
$Host.Runspace.ThreadOptions = "ReuseThread"
Try{
#Get the Folder
$pFolder = $ctx.Web.GetFolderByServerRelativeUrl($FolderRelativeURL)
$ctx.Load($pFolder)
$ctx.ExecuteQuery()
#Get permissions assigned to the Folder
$RoleAssignments = $pFolder.ListItemAllFields.RoleAssignments
$ctx.Load($RoleAssignments)
$ctx.ExecuteQuery()
#Loop through each permission assigned and extract details
$PermissionCollection = @()
Foreach($RoleAssignment in $RoleAssignments)
{
$ctx.Load($RoleAssignment.Member)
$ctx.executeQuery()
#Get the User Type
$PermissionType = $RoleAssignment.Member.PrincipalType
#Get the Permission Levels assigned
$ctx.Load($RoleAssignment.RoleDefinitionBindings)
$ctx.ExecuteQuery()
$PermissionLevels = ($RoleAssignment.RoleDefinitionBindings | Select -ExpandProperty Name) -join ","
#Get the User/Group Name
$Name = $RoleAssignment.Member.LoginName # $RoleAssignment.Member.LoginName
#Add the Data to Object
$Permissions = New-Object PSObject
$Permissions | Add-Member NoteProperty Name($Name)
$Permissions | Add-Member NoteProperty Type($PermissionType)
$Permissions | Add-Member NoteProperty PermissionLevels($PermissionLevels)
$PermissionCollection += $Permissions
}
Return $PermissionCollection
}
Catch {
write-host -f Red "Error Getting Folder Permissions!" $_.Exception.Message
}
}
##################################
#### Parmeters and start script ##
##################################
$admin=""
$pass= ConvertTo-SecureString "" -AsPlainText -Force
$SiteURL="https://micrososft.sharepoint.com/sites/hgs_demo/"
$LibraryName="FolderTest";
$SrcFolderName="mytest"
$NewFolderName="cmytesst"
$global:ctx
Try {
Connect-SPO -Username $admin -Url $SiteURL -AdminPassword $pass
$Library=$ctx.Web.Lists.GetByTitle($LibraryName);
$Folders = $Library.RootFolder.Folders
$ctx.Load($Library);
$ctx.Load($Folders)
$ctx.ExecuteQuery()
foreach ($Folder in $Library.RootFolder.Folders)
{
if($Folder.ItemCount -gt 0 -and $Folder.Name -eq $SrcFolderName)
{
$CurrentRootfolderurl= $Folder.ServerRelativeUrl
$NewRootFolderUrl=$CurrentRootfolderurl.Replace($SrcFolderName,$NewFolderName)
#CheckIfFolderExists
$CheckRootFolderExists= Check-SPOFolderExists -FolderRelativeURL $NewRootFolderUrl
if( $CheckRootFolderExists -eq "True")
{
Write-Host "A folder with name "$NewFolderName "already Exists and its url " $NewRootFolderUrl -ForegroundColor Green
}
else{
#Calling Recursive Function with
Recurse $Folder
}
}
}
}
catch{
Write-Host $_.Exception.Message
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit sharepoint.stackexchange