1. Home
  2. Guides
  3. Power Automate
  4. How to send a mail merge with 2 or 3 attachments per person in Power Automate
Power Automate

How to send a mail merge with 2 or 3 attachments per person in Power Automate

Build a Power Automate flow that sends each person one email with exactly their own files from OneDrive, then marks the Excel row as sent so a second run never mails anyone twice.

Jump to a step (12)
Who this is for

This is for anyone who sends invoices, payslips or certificates to many people from an Excel list. The common mail merge flow that uses Find files in folder sends the same email several times, attaches the wrong files or the Excel file itself, and loses files when a person has two or three. This fixed flow gets every file by its exact path and sends one email per person.

The old flow searches the folder with OneDrive search. That search reads inside files and matches similar names, so the Excel file (which lists every file name) matches for every customer, and the timesheet can rank above the invoice. Because the Send an email action sat inside the file loop, every match sent another email. In my test, it sent 13 emails for 5 customers. The new flow splits the file names, gets each file directly, collects them in a list and sends one email at the end.

What you need

  • A Microsoft 365 work or school account with Power Automate
  • Standard connectors only: Excel Online (Business), OneDrive for Business and Office 365 Outlook. No premium license and no SharePoint needed
  • An Excel file in OneDrive with a table (in the demo it is called Customers) with the columns ID, Customer, Email, Files and Sent
  • All the PDF files in one OneDrive folder, with names that match the Files column exactly
  • Optional: the Excel template and all the expressions, free to download on this page

Step by step

0 of 12 done
  1. 01

    Prepare the Excel table and the files

    Create a table with one row per person and the columns ID, Customer, Email, Files and Sent. In Files, list each person's file names separated by a semicolon. Leave Sent empty. Put all the PDFs in one OneDrive folder (in the demo, Invoices) and check that the names match exactly.

  2. 02

    Create an instant cloud flow

    In Power Automate, click Create, then Instant cloud flow. Give the flow a name, select Manually trigger a flow and click Create. You run the flow by hand whenever the files are ready.

  3. 03

    Add the Attachments variable

    Click the plus icon below the trigger and add Initialize variable. Set the name to Attachments, the type to Array and the value to []. This empty list will hold the files for one person.

  4. 04

    Read only the unsent rows from Excel

    Add List rows present in a table. Choose OneDrive for Business, the document library OneDrive, your Excel file and the table. Under Advanced parameters, select Filter Query and type Sent eq ''. This returns only the rows where the Sent column is empty.

  5. 05

    Loop through the customers and reset the list

    Add Apply to each, rename it to For each customer and set the input to body value from List rows. Inside the loop, add Set variable, select Attachments and set the value to []. Without this reset, the second person would also get the first person's files.

  6. 06

    Loop through the file names

    Below Set variable, add another Apply to each and rename it to For each file. For the input, click the fx icon and add this expression, then click Add:

    • split(items('For_each_customer')?['Files'], ';')

    The loop now runs once for every file name in the row. Leave concurrency control off for both loops, which is the default.

  7. 07

    Get each file by its exact path

    Inside For each file, add Get file content using path for OneDrive for Business (not the SharePoint one). For the file path, click fx and add concat('/Video demos/Invoices/', trim(items('For_each_file'))), changing the folder path to your own. The trim removes the space after each semicolon, and there is no search, so the Excel file is never picked.

  8. 08

    Add each file to the list

    Below Get file content using path, add Append to array variable and select Attachments. Build the value in this order:

    • Type {"Name": "
    • Add the expression trim(items('For_each_file'))
    • Type ", "ContentBytes":
    • Add the dynamic content File content
    • Type }

    This is the name and content format the email action needs for attachments.

  9. 09

    Send one email per customer

    Click the plus icon below For each file, still inside For each customer, and add Send an email (V2). For To, click the gear icon, select Use dynamic content and pick Email. Type a subject and a body with the Customer dynamic content. Under Advanced parameters, select Attachments, click Switch to input entire array and select the Attachments variable.

  10. 10

    Mark the row as sent

    Below Send an email (V2), add Update a row and pick the same location, library, file and table. Set the key column to ID and the key value to the ID dynamic content. Click Show all, and in the Sent field add the expression formatDateTime(utcNow(), 'yyyy-MM-dd').

  11. 11

    Save and test the flow

    Click Save, then Test, select Manually and click Test. Click Continue, Run flow and Done. In the run, For each customer should show one run per row, and Send an email should run once per customer.

  12. 12

    Check the emails and run it again

    In Outlook, open Sent Items and check that each person got one email with only their own files. The Sent column in Excel now shows today's date. Run the flow again, and List rows returns no rows, so nobody gets a second email.

Tips and common problems

  • The file names in the Files column must match the files in OneDrive exactly. If one name is wrong, Get file content using path fails for that person.
  • Keep trim in both expressions. Without it, the space after each semicolon becomes part of the file name and the file is not found.
  • Leave concurrency control off on both loops. The Attachments variable is shared, so parallel runs can mix up people's files.
  • Place Send an email (V2) below For each file, not inside it. Inside the file loop, it sends one email per file again.
  • To send to someone a second time, clear their Sent cell. The filter query only reads rows where Sent is empty.
  • Test with your own address first. Example addresses like example.com show up in Sent Items but cannot receive email.
Still stuck? Ask AI to help you fix itChatGPTClaudeGeminiCopilotPerplexityGrok

Questions

Do I need a premium license or SharePoint?

No. The flow uses only the standard Excel Online (Business), OneDrive for Business and Office 365 Outlook connectors.

Why did my old flow attach the Excel file?

Find files in folder uses OneDrive search, which also reads inside files. Your Excel file lists every file name, so it matches for every person.

Can I keep the Excel file in the same folder as the PDFs?

Yes. This flow gets each file by its exact path instead of searching, so the Excel file is never picked.

How many files can one person get?

The file loop runs once for every name in the Files cell, so you can list as many as you need, separated by semicolons.

Why does a second run send nothing?

After each email, the flow writes today's date into the Sent column, and the filter query Sent eq '' skips rows that have a date.

Video chapters

Files for this guide

ZIP
Mail Merge With Multiple Attachments Fixed
Download

Flow package (.zip)? How to import it into your Power Automate.

Ask a question in the comments Last checked 2 Nov 2026. Screens change: if a step looks different, tell me in the comments.