1

This is the first PowerShell-script I ever wrote.

I want to keep digging into the folder 10 times. Is there a better way to do this than my way to keep repeating?

Here is the script:

# Connect Connect-PnPOnline -Url https://site.sharepoint.com/sites/atp/tt -Interactive # Get parentSource folder $parentSource="SourceLibrary/SourceFolder" # Get parentTarget folder $parentTarget="TargetLibrary3/TargetFolder" $parentSourceFolders = Get-PnPFolderItem $parentSource # start loop to folders/files in the parentSource folder # if childFolder already in parentTarget folder Foreach ($folder in $parentSourceFolders) { $TargetFolder = $parentTarget + "/" + $folder.Name Copy-PnPFile -SourceUrl $parentSource/$($folder.Name) -TargetUrl $TargetFolder -Force -OverwriteIfAlreadyExists Write-Host "COPY:" $parentSource/$($folder.Name) Write-Host "PASTE:" $TargetFolder if(Get-PnPFolderInFolder -FolderSiteRelativeUrl $parentSource/$($folder.Name)){ # start another loop to folders/files in the childFolder $childFolder1stSubfolders = Get-PnPFolderInFolder -FolderSiteRelativeUrl $parentSource/$($folder.Name) Foreach ($sub1folder in $childFolder1stSubfolders) { Copy-PnPFile -SourceUrl $parentSource/$($folder.Name)/$($sub1folder.Name) -TargetUrl $TargetFolder/$($sub1folder.Name) -Force -OverwriteIfAlreadyExists Write-Host "COPY:" $parentSource/$($folder.Name)/$($sub1folder.Name) Write-Host "PASTE:" $TargetFolder/$($sub1folder.Name) if(Get-PnPFolderInFolder -FolderSiteRelativeUrl $parentSource/$($folder.Name)/$($sub1folder.Name)){ $childFolder2ndSubfolders = Get-PnPFolderInFolder -FolderSiteRelativeUrl $parentSource/$($folder.Name)/$($sub1folder.Name) Foreach ($sub2folder in $childFolder2ndSubfolders) { Copy-PnPFile -SourceUrl $parentSource/$($folder.Name)/$($sub1folder.Name)/$($sub2folder.Name) -TargetUrl $TargetFolder/$($sub1folder.Name)/$($sub2folder.Name) -Force -OverwriteIfAlreadyExists Write-Host "COPY:" $parentSource/$($folder.Name)/$($sub1folder.Name)/$($sub2folder.Name) Write-Host "PASTE:" $TargetFolder/$($sub1folder.Name)/$($sub2folder.Name) } } } } } 
2
  • What's the main goal here? Copy all the contents from on library folder to another library but only ten levels deep in the source library? Commented May 27, 2024 at 7:26
  • Yes, as well as overwrite the existing folders because manual 'copy to' does not accept replacing folders if they exist. Thanks! Commented May 28, 2024 at 5:52

2 Answers 2

0

Got caught up with some other things. This script should do what you want.

Please note that if you set the path at $SouceLibrary to an existing nested folder, the depth will then be included in the $maxLevel total as I count slashes (/) for each folders path.

I'm sure that there's plenty of stuff that could be improved but I can't put any more time into it. :)

# Connect to SPO Connect-PnPOnline -Url "https://site.sharepoint.com/sites/atp/tt" -Interactive # Source library/folder $sourceFolder = "SourceLibrary/One Folder" # Destination library/folder $destinationFolder = "DestinationLibrary/My existing folder" # Count the current depth in the source folder path (-1 to exclude the library/rootfolder) $sourceFolderDepth = ($sourceFolder -split "/").Count -1 # Limit how deep to traverse in the source library folder structure $maxLevel = 5 # If $sourceFolder is the rootfolder (the actual library), filter out the default folder $filteredItems = @("Forms", "Document", "AllItems.aspx", "Combine.aspx", "DispForm.aspx", "EditForm.aspx", "repair.aspx", "template.dotx", "Thumbnails.aspx", "Upload.aspx") # Get all folders recursively $folders = Get-PnPFolderItem -FolderSiteRelativeUrl $sourceFolder -ItemType Folder -Recursive | Where-Object { $_.Name -notin $filteredItems} # Loop through all the folders foreach($folder in $folders) { # Count the number of folders in the current item path to determine how deep down in the folder hierarchy we are $folderPathCount = $(($folder.ServerRelativeUrl -split "$sourceFolder")[1] -replace "/$($folder.Name)", '').Split("/").Count + $sourceFolderDepth # Check if the current folder path is less than or equal to the maxlevel set if($folderPathCount -le $maxLevel) { # Build the source path $sourcePath = $($folder.ServerRelativeUrl -split $sourceFolder)[1] # Build the destination path $destinationPath = $destinationFolder + $($sourcePath.Substring(0, $sourcePath.LastIndexOf('/'))) # Check if the current folder already exist before trying to create it $currentFolder = Get-PnPFolder -Url $($destinationPath + "/" + $folder.Name) -ErrorAction SilentlyContinue if($null -eq $currentFolder) { # Create the folder as it does not exist Add-PnPFolder -Folder $destinationPath -Name $folder.Name | Out-Null } # Get all files in the current folder $files = Get-PnPFolderItem -FolderSiteRelativeUrl $($sourceFolder + $sourcePath) -ItemType File | Where-Object { $_.Name -notin $filteredItems} # Loop through all the files in the current folder foreach($file in $files) { # Check if the file already exist before trying to copy it if(-not(Get-PnPFolderItem -FolderSiteRelativeUrl $($destinationPath + "/" + $folder.Name) -ItemName $file.Name)) { # Copy the file if it does not already exist - use force to skip confirmation Copy-PnPFile -SourceUrl $file.ServerRelativeUrl -TargetUrl $($destinationFolder + $sourcePath) -Force } } } # We've reached the maxlevel, stop the loop else { break; } } 
0

You should make it as a function and use recursion. It would seem cleaner.

function Overwrite-MyFolders { yourcode Overwrite-MyFolders -ParentSourceFolders $parentSourceFolders } 

A nice simple example + explanation can be found here

Function Get-Ps1File { Param ($Path= '.\') Get-ChildItem -Path $Path | ForEach-Object { If ($_.Name -like "*.ps1") { $_.Name } ElseIf ($_.PSIsContainer) { Get-Ps1File -Path $_.FullName } # End If-ElseIf. } # End ForEach-Object. } # End Function: Get-Ps1File. 

If you want the function to roll EXACTLY 10 times you can put a condition checking, e.g. for the path length or the number of "/".

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.