What I Built

I built an Azure Logic App that recursively copies all files and subfolders from a folder in one OneDrive account to another, preserving the full folder structure and only copying files that have not been modified in the last 30 days.

Tech Stack

Azure Logic Apps (Consumption)
OneDrive for Business connectors
Dynamic expressions and variables
GitHub for hosting JSON code

My Goals

Recursively copy all files from a OneDrive folder and its subfolders
Only copy files that have not been modified in the last 30 days
Maintain the original folder structure in the destination

How It Works

1

Use a recurrence trigger

Set up automated scheduling for the copy process

2

Get root folder ID via metadata lookup

Identify the starting point for the recursive operation

3

Initialize variables for folder queue and current context

Set up the tracking mechanism for processing

4

Use an Until loop to walk folders recursively

Iterate through all folders and subfolders

5

List children in each folder, append subfolders to the queue

Discover and queue additional folders for processing

6

Copy eligible files with updated paths

Transfer files that meet the criteria to the destination

Challenges I Faced

No folder trigger or folder metadata action

Logic Apps doesn't provide a dedicated trigger for changes in OneDrive folders, nor does it have a clear action named "Get folder metadata." I initially searched for a way to target folders directly but realized the available "Get file metadata using path" action also works for folders. Once I confirmed that folders could be treated as file items, I used this action with a path like / to retrieve the root folder ID and continue from there.

Path-based access failed

At first, I tried using folder paths (like /TSLog) in the Logic App to access subfolders. However, I consistently received 404 errors, even though the folders existed. The fix came from inspecting the Logic App's behavior in code view: I noticed it was using double-encoded OneDrive item IDs instead of folder paths. I switched the folder listing logic to use:

encodeURIComponent(encodeURIComponent(id))

instead of a plain path, and it worked flawlessly.

SetVariable logic was out of order

In the Until loop, I was pulling the current folder values (id, name, path) from the foldersToProcess array. However, I placed the SetVariable steps before updating the array with skip(...). As a result, the same folder was processed repeatedly. I resolved this by placing the SetVariable steps after the array was updated with skip(variables('foldersToProcess'), 1), so each loop correctly pulled the next folder to process.

Array wasn't updating

I used a Compose action to get the updated array of folders with @skip(...), but forgot to assign its output back to the foldersToProcess variable. Without that assignment, the array never changed, and I kept seeing the loop process the same folder repeatedly. I fixed this by adding a SetVariable step that stored the output of Compose into foldersToProcess.

lastModifiedDateTime was wrong

I tried filtering files based on a property called lastModifiedDateTime, assuming it was a standard field. This led to runtime errors because that field didn't exist in the OneDrive metadata response. After checking the actual response from the OneDrive API, I found that the correct property was LastModified. I updated my condition to compare against that field, and the date filtering worked as expected.

Folder Structure Preservation

I added a path property to every folder in the queue and used that to recreate subfolders in the destination. Files are saved under /TSLogArchive/{relativePath}.

Full Code View on GitHub

You can find the full Logic App JSON here. Just update the OneDrive connections and root folder ID to make it your own.

Pro Tip: The GitHub repository contains the complete JSON export that you can import directly into your Azure Logic App instance.

Lessons Learned

Always validate what Logic Apps puts into expressions
Debug with Compose steps frequently
Using item IDs is more reliable than paths
Dynamic content often inserts strings, not true expressions

What's Next?

Add email notification on completion
Track copy history or audit log
Enhance with file type filters or metadata sync

Wrap-Up

This Logic App makes it easy to sync content between OneDrive accounts, fully automated and low-code. I hope it saves you time and effort. Contributions welcome!

View on GitHub
Author

Ofir Gavish

Microsoft MVP in Security | Cloud Infrastructure Team Lead | Azure & Microsoft 365 Expert

Share this article

Related Articles

Event Calendar Automation

Automate calendar events with Microsoft Graph and Power Automate for seamless scheduling.

Read More

SharePoint Download Report

Generate comprehensive download reports for SharePoint files with PowerShell automation.

Read More

Search Azure Key Vault

Efficiently search and manage secrets across multiple Azure Key Vault instances.

Read More