Copying contents of Sharepoint folder (but not actual folder) up a directory in the same site

239 Views Asked by At

I'm attempting to remove some unnecessary parents folders from our Sharepoint Online sites in Powershell now that we've changed our policies regarding file retention. We want to get rid of the pre-existing 2020 folder to minimise the folder structure complexity for users to navigate, and ensure they don't create a folder for 2021 and copy files into there, taking up Sharepoint space.

As such I'm looking to extract the contents of the 2020 folder in all of our Teams sites to the 'Shared Documents/General' location, then delete the empty 2020 folder. So it goes from

'Shared Documents/General/2020/[all content]'

to

'Shared Documents/General/[all content]'

The MovePnP-Folder function naturally moves the entire folder, but it's the folder itself (not its contents) I'm looking to get rid of. The MovePnP-File function appears to work in strange ways and tells me I don't have rights to move files when I try, despite being a Global Admin. It also doesn't appear to work with wildcards, which I'd be expecting to use to ensure all the contents of a folder are selected.

I'm looking to have this recur for all the Teams sites in our environment.

May I have some assistance here, please?

1

There are 1 best solutions below

2
On

We can enumerate the folder and move its files/subfolders in a loop. Please take a reference of below demo:

#Load SharePoint CSOM Assemblies
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.Runtime.dll"
  
Function Move-SPOFilesBetweenFolders
{
  param
    (
        [Parameter(Mandatory=$true)] [string] $SiteURL,
        [Parameter(Mandatory=$true)] [Microsoft.SharePoint.Client.Folder] $SourceFolder,
        [Parameter(Mandatory=$true)] [Microsoft.SharePoint.Client.Folder] $TargetFolder
    )
    Try {
        #Write-host "Copying Files from '$($SourceFolder.ServerRelativeUrl)' to '$($TargetFolder.ServerRelativeUrl)'"
        #Get all Files from the source folder
        $SourceFilesColl = $SourceFolder.Files
        $Ctx.Load($SourceFilesColl)
        $Ctx.ExecuteQuery()
  
        #Iterate through each file and move
        Foreach($SourceFile in $SourceFilesColl)
        {
            #Get all files from source Folder
            $SourceFile =$Ctx.Web.GetFileByServerRelativeUrl($SourceFile.ServerRelativeUrl)
            $Ctx.Load($SourceFile)
            $Ctx.ExecuteQuery()
              
            #Move File to destination
            $TargetFileUrl = $SourceFile.ServerRelativeUrl -Replace $SourceFolderURL,$TargetFolderURL
            $SourceFile.MoveTo($TargetFileUrl, [Microsoft.SharePoint.Client.MoveOperations]::Overwrite)
            $Ctx.ExecuteQuery()
  
            Write-host -f Green "File Moved to: "$TargetFileURL
        }
  
        #Process Sub Folders
        $SubFolders = $SourceFolder.Folders
        $Ctx.Load($SubFolders)
        $Ctx.ExecuteQuery()
        Foreach($SubFolder in $SubFolders)
        {
            If($SubFolder.Name -ne "Forms")
            {
                #Prepare Target Folder
                $EnsureFolderURL = $SubFolder.ServerRelativeUrl -Replace $SourceFolderUrl, $TargetFolderUrl
                Try {
                        $Folder=$Ctx.web.GetFolderByServerRelativeUrl($EnsureFolderURL)
                        $Ctx.load($Folder)
                        $Ctx.ExecuteQuery()
                    }
                catch {
                        #Create Folder
                        if(!$Folder.Exists)
                        {
                            $Folder=$Ctx.Web.Folders.Add($EnsureFolderURL)
                            $Ctx.Load($Folder)
                            $Ctx.ExecuteQuery()
                            Write-host "New Folder Created:"$SubFolder.Name -f Yellow
                        }
                    }
                #Call the function recursively to move all files from source folder to target
                Move-SPOFilesBetweenFolders -SiteURL $SiteURL -SourceFolder $SubFolder -TargetFolder $Folder
 
                #Remove the Source Folder
                $SubFolder.Recycle() | Out-Null
                $Ctx.ExecuteQuery()
            }
        }
    }
    Catch {
        write-host -f Red "Error Moving File:" $_.Exception.Message
    }
}
  
#Set Parameter values
$SiteURL="https://abc.sharepoint.com/sites/s01"
$SourceFolderURL ="/sites/s01/My test doc lib/SDK/testlongpath/SPServices"
$TargetFolderURL ="/sites/s01/My test doc lib"
  
#Setup Credentials to connect
$Cred= Get-Credential
  
#Setup the context
$Ctx = New-Object Microsoft.SharePoint.Client.ClientContext($SiteURL)
$Ctx.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Cred.Username, $Cred.Password)
       
#Get the source and Target Folders
$SourceFolder=$Ctx.Web.GetFolderByServerRelativeUrl($SourceFolderURL)
$Ctx.Load($SourceFolder)
$TargetFolder=$Ctx.Web.GetFolderByServerRelativeUrl($TargetFolderURL)
$Ctx.Load($TargetFolder)
$Ctx.ExecuteQuery()
 
#Call the function
Move-SPOFilesBetweenFolders -SiteURL $SiteURL -SourceFolder $SourceFolder -TargetFolder $TargetFolder

BR