Copy and mirror folder structure permissions on Sharepoint online site

tech cons 1 Reputation point
2021-07-22T10:13:07.843+00:00

Hello!

I need to mirror the source folder structure with permissions to destination folder (with inheritance) on Sharpeoint site. I have found the script on the web, which execution ends with:

Error Granting permission to Folder! Exception calling "ExecuteQuery" with "0" argument (s): "The 'Shared Documents' list does not exist on the site with the URL ..'."

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

}

Could you please help to solve the problem or there are another way / script to do it?

Thanks!

SharePoint
SharePoint
A group of Microsoft Products and technologies used for sharing and managing content, knowledge, and applications.
10,846 questions
SharePoint Development
SharePoint Development
SharePoint: A group of Microsoft Products and technologies used for sharing and managing content, knowledge, and applications.Development: The process of researching, productizing, and refining new or existing technologies.
3,047 questions
{count} votes

3 answers

Sort by: Most helpful
  1. RaytheonXie_MSFT 36,171 Reputation points Microsoft Vendor
    2021-07-26T06:04:33.027+00:00

    Hi @tech cons ,
    There some error in the function of connect to sharepoint online. I have modified some code and try following sample Please:

     ########################################  
     #### 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="admin"  
     $pass= ConvertTo-SecureString "password" -AsPlainText -Force  
     $SiteURL="url"  
     $LibraryName="FolderTest";  
     $SrcFolderName="22"  
     $NewFolderName="Document"  
      
        
    #Get Credentials to connect to SharePoint Online site  
    #$Cred = Get-Credential  
      
    #$UserName="account"  
    #$Password = "password"  
          
    #Set up the context  
    $ctx = New-Object Microsoft.SharePoint.Client.ClientContext($SiteUrl)  
    $ctx.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($admin, $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)  
             {  
         $ctx.Load($Folder);  
      $ctx.ExecuteQuery()   
             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  
                  }  
                }  
             }  
    

    If an Answer is helpful, please click "Accept Answer" and upvote it.
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    0 comments No comments

  2. tech cons 1 Reputation point
    2021-07-26T10:37:35.757+00:00

    Hi,
    thanks for the corrections. Now it works on library with latin characters with spaces. I have library name with Spanish characters and spaces (Documentación Principal) and the script does not work and ends with the same error. Is there any way to fix url without changing the folder name?
    have tried

      $LibraryName="Documentacin Principal";
         $LibraryName="Documentación Principal";
         $LibraryName="Documentacin%20Principal"; 
    

  3. tech cons 1 Reputation point
    2021-07-26T12:55:50.25+00:00

    Also I can't find the answer how to do with folder structure if the folder to be copied is under the multiple folders path.
    for example

      $SrcFolderName="11/111/111/22"
      $NewFolderName="11/111/111/Document"
    

    I tried the way I wrote above but the script has ended without error and noting gets copied.
    Thanks!

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.