This example will show a case where I want to run a reoccurring flow to go through a document library and any folder marked for Archiving it will move it and all files in the directory into a new document library

If you want to preserve the created date, created by, modified date, and modified by fields then on the archive document library create fields for that information. I created the following columns on the Archive document library

  • oCreated (Date)
  • oCreatedBy (People Picker)
  • oModified (Date)
  • oModifiedBy (People Picker)
  • Product (Choice: Choice 1/Choice 2/Choice 3)
  • Cost (Number)

on the Source document library I created the following columns

  • Archive (Choice: Yes/No)
    • I chose NOT to use the yes/no column type because I could not get the boolean to filter proper for some reason
  • Product (Choice: Choice 1/Choice 2/Choice 3)
  • Cost (Number)

Below is my example Source Document library

On the far right you will notice I have the following folder and nested folders marked for Archiving

  • Something1
  • Something2/test
  • Something2/TwoDeep/ThreeDeep

Here is a quick look at the flow and I will break it down if you keep scrolling (This will only work for Folders. I don’t have any checks for files marked Yes on Archive so it will fail for files)

Create a new flow and select the trigger you are needing (I won’t go over this part. I selected a Scheduled Flow)

I have created 4 Initialize Variable Actions like so

Next I will get the properties of ANY item marked for archiving equal to yes

  • Library name: Is the name of my original source document library
  • Filter Query: This is the name of the column to filter by
  • Order By: I did this to order all the files ascending by their folder name

Now I create an Apply to Each action and add the value from the above

@{outputs('Get_files_(properties_only)')?['body/value']}

Inside the apply to each I created each of the following actions

Compose CreateArray from FullPath

@{split(items('Apply_to_each_FolderPath')?['{FullPath}'], '/')}

Condition to Handle Nested Folders

empty(skip(outputs('Compose_CreateArray_from_FullPath'),2))

Compose Remove First and Last Folder

@{take(skip(outputs('Compose_CreateArray_from_FullPath'), 1), add(length(outputs('Compose_CreateArray_from_FullPath')), -2))}

Next I created the following actions

Join

@{outputs('Compose_Remove_First_and_Last_Folder')}

Set variable TruncatedFolder

/@{body('Join')}

Create new folder

@{variables('TruncatedFolder')}

Get folder metadata using path

/SourceTest@{variables('TruncatedFolder')}

Get file properties

@{outputs('Get_folder_metadata_using_path')?['body/ItemId']}

Next create and Update file properties action

ID

@{outputs('Create_new_folder')?['body/ID']}

Title

@{outputs('Get_file_properties')?['body/Title']}

You will repeat the steps for any other columns needing to match on the new folder

@outputs('Get_file_properties')?['body/Product/Value']
@{outputs('Get_file_properties')?['body/Cost']}
@{outputs('Get_file_properties')?['body/Created']}
@outputs('Get_file_properties')?['body/Author/Claims']
@{outputs('Get_file_properties')?['body/Modified']}
@outputs('Get_file_properties')?['body/Editor/Claims']
@{outputs('Get_file_properties')?['body/OData__ExtendedDescription']}

The next step is copy folder (you may be able to use move folder to avoid any delete cleanup steps at the end of the flow)

Folder to Copy

/@{items('Apply_to_each_FolderPath')?['{FullPath}']}

Destination Folder

/ArchiveTest@{variables('TruncatedFolder')}

Add an Update File Properties action

ID

@{outputs('Copy_folder')?['body/ItemId']}

oCreated

@{items('Apply_to_each_FolderPath')?['Created']}

oCreatedBy Claims

@items('Apply_to_each_FolderPath')?['Author/Claims']

oModified

@{items('Apply_to_each_FolderPath')?['Modified']}

oModifiedBy Claims

@items('Apply_to_each_FolderPath')?['Editor/Claims']

Create a Get files (properties only) action for Archive Test

Limit Entries to Folder

@outputs('Copy_folder')?['body/Path']

In the below pic I forgot to include the Order By field under advanced options

Order By

FileLeafRef asc

I will then create the same action but for Source Test

Limit Entries to Folder

/@{items('Apply_to_each_FolderPath')?['{FullPath}']}

Order By

FileLeafRef asc

Next I created a Select Action with the following Map

From

@{outputs('Get_files_(properties_only)_of_Source_Test')?['body/value']}

The map info is the same as above for oCreated, oCreatedBy, oModified, oModifiedBy

Create a set variable action to set ColumnPropertiesArray

@{body('Select_Source_Column_Data')}

Create a new Apply to each action and put a Compose and Parse JSON action inside with the following expressions and output

Select an output from previous steps

@{outputs('Get_files_(properties_only)_of_Archive_Test')?['body/value']}

Compose FirstIndex of CoumnPropertiesArray

Inputs

@{first(variables('ColumnPropertiesArray'))}

Parse JSON

Content

@{outputs('Compose_FirstIndex_of_ColumnPropertiesArray')}

Schema

{
    "type": "object",
    "properties": {
        "oCreated": {
            "type": "string"
        },
        "oCreatedBy": {
            "type": "string"
        },
        "oModified": {
            "type": "string"
        },
        "oModifiedBy": {
            "type": "string"
        }
    }
}

Create an Update file properties for ArchiveTest

ID

@{items('Apply_to_each_FileFound')?['ID']}

oCreated

@{body('Parse_JSON')?['oCreated']}

oCreatedBy Claims

@body('Parse_JSON')?['oCreatedBy']

oModified

@{body('Parse_JSON')?['oModified']}

oModifiedBy Claims

@body('Parse_JSON')?['oModifiedBy']

For the last three steps I created an Increment variable, Compose, and Set variable action

Increment variable Counter

Value

1

Compose Skip to the Next ColumnPropertiesArray Index

Inputs

@{skip(variables('ColumnPropertiesArray'), 1)}

Set variable Column PropertiesArray NextIndex

Value

@{outputs('Compose_Skip_to_Next_ColumnPropertiesArray_Index')}

This flow as is won’t delete the Source folder so if you want that done steps will need added that I am not going to cover at this time or you can scroll up and on the copy folder action a move folder action should work

Also this current flow will preserve the Created, CreatedBy, Modified, and ModifiedBy values to the new archive columns created so if you don’t need that requirement the final Apply to each can be removed

This was a long post but I hope it helps someone and is not too confusing