Tutorials//Faster PDF Form Filling with Power Automate Desktop and PowerShell
intermediate

Faster PDF Form Filling with Power Automate Desktop and PowerShell

Skip the slow UI automation approach—use a PowerShell script inside Power Automate Desktop to fill PDF forms quickly and reliably.

NA
Narmer Abader
@narmer · Published June 3, 2026

Filling PDF forms is a common task in business document automation, but it can become a bottleneck when you rely on UI automation. Power Automate Desktop (PAD) does not natively recognise form fields inside a PDF file, forcing you to simulate slow keyboard and mouse actions to jump from field to field. Even worse, any change in screen resolution or scaling can break the automation.

Instead, you can bypass the UI entirely by using a PowerShell script that directly writes values into the PDF’s AcroForm fields. Combined with a simple loop in PAD, this approach is faster, more reliable, and easier to maintain.

In this article you will build an automation that reads data from a CSV file and fills a purchase order PDF template — all without touching the keyboard or mouse.

Why UI Automation Falls Short for PDF Forms

When you try to use the standard “Send Keys” or “Click” actions on a PDF form, PAD cannot identify the individual text input fields. The only workaround is to send a series of tab and arrow keys to move from one field to another, then type each value. This technique has several drawbacks:

  • Speed — you must wait for the PDF viewer to process each keystroke.
  • Fragility — a pop-up or background notification can steal focus and break the sequence.
  • Maintenance — every change to the PDF layout requires updating the tab order.

Using PowerShell eliminates these issues because the data is written directly into the PDF’s internal field collection.

Our Scenario: Filling Purchase Order PDFs

Imagine you work for a parts distributor and you need to generate a purchase order PDF for every incoming order. Each order arrives in a CSV file that contains the following columns:

PO_NumberPO_DateVendorPart_NumberQtyUnit_PriceTotal
PO-10012026-06-03Acme SuppliesA-12341025.50255.00
PO-10022026-06-03Beta ComponentsB-56782512.00300.00

Your goal is to fill a PDF template named PurchaseOrderTemplate.pdf that contains fields matching these column names.

Step 1: Prepare Your PDF Form

You need a fillable PDF — also called an AcroForm. If you don’t have one yet, you can create it using Microsoft Word (save as PDF and enable “Best for print”, then open in Adobe Acrobat to add form fields) or any PDF editor.

Write down the exact names of the form fields. You can often find them by right‑clicking on a field and selecting Properties in Adobe Acrobat. In this example we’ll use the field names that match our CSV columns: PO_Number, PO_Date, Vendor, Part_Number, Qty, Unit_Price, and Total.

Place the template in a folder that PAD can access, for example C:\PADPdfFiller\.

Step 2: Obtain the Required Libraries

PowerShell cannot manipulate PDF forms without a third‑party library. The most common free library is iTextSharp, and it depends on BouncyCastle. Both are distributed via NuGet.

  1. Go to the iTextSharp NuGet page and download the package.
  2. Go to the BouncyCastle NuGet page and download the package.
  3. In Windows Explorer, rename both .nupkg files to .zip and extract them.
  4. Inside each extracted folder locate the .dll files:
    • itextsharp.dll
    • BouncyCastle.Crypto.dll
  5. Copy both DLLs into your working folder (C:\PADPdfFiller\).

Step 3: Discover PDF Field Names with PowerShell

Before you can write a filling script, you need to confirm the exact field names stored in the PDF. Open Windows PowerShell ISE (or any editor) and run a script that lists every field.

powershellList PDF Field Names
Add-Type -Path "C:\PADPdfFiller\itextsharp.dll"
Add-Type -Path "C:\PADPdfFiller\BouncyCastle.Crypto.dll"

$PdfPath = "C:\PADPdfFiller\PurchaseOrderTemplate.pdf"
$Reader = New-Object iTextSharp.text.pdf.PdfReader($PdfPath)
$Fields = $Reader.AcroFields.Fields
Write-Output $Fields
$Reader.Close()

The output will show the internal field names. If they don’t match your expected names, you’ll need to adjust either your CSV headers or the field properties in the PDF.

Step 4: Write the Filling Script

Now create a PowerShell script that accepts the data and writes it into the PDF. The script below uses environment variables to receive values from PAD, but you could also pass them as arguments (environment variables are simpler for demonstration).

powershellFill-PDF.ps1
Add-Type -Path "C:\PADPdfFiller\itextsharp.dll"
Add-Type -Path "C:\PADPdfFiller\BouncyCastle.Crypto.dll"

$InputPdf = "C:\PADPdfFiller\PurchaseOrderTemplate.pdf"
$OutputDir = "C:\PADPdfFiller\FilledPOs\"

$OutputPdf = Join-Path $OutputDir "PO_$([System.Environment]::GetEnvironmentVariable('PO_Number')).pdf"

$Reader = New-Object iTextSharp.text.pdf.PdfReader($InputPdf)
$Stamper = New-Object iTextSharp.text.pdf.PdfStamper($Reader, [System.IO.File]::Create($OutputPdf))

# Build a hashtable from environment variables
$Data = @{
  PO_Number  = [System.Environment]::GetEnvironmentVariable('PO_Number')
  PO_Date    = [System.Environment]::GetEnvironmentVariable('PO_Date')
  Vendor     = [System.Environment]::GetEnvironmentVariable('Vendor')
  Part_Number = [System.Environment]::GetEnvironmentVariable('Part_Number')
  Qty        = [System.Environment]::GetEnvironmentVariable('Qty')
  Unit_Price = [System.Environment]::GetEnvironmentVariable('Unit_Price')
  Total      = [System.Environment]::GetEnvironmentVariable('Total')
}

foreach ($Field in $Data.GetEnumerator()) {
  $Stamper.AcroFields.SetField($Field.Key, $Field.Value)
  $Stamper.AcroFields.SetFieldProperty($Field.Key, "setfflags", [iTextSharp.text.pdf.PdfFormField]::FF_READ_ONLY, 0)
}

$Stamper.Close()
$Reader.Close()
Read‑only fields

Setting the form to read‑only prevents accidental editing. If you need to allow later changes, simply remove the SetFieldProperty lines.

Save this script as Fill-PDF.ps1 in the same folder as the DLLs and template.

Step 5: Integrate with Power Automate Desktop

In your PAD flow you will:

  1. Read CSV file — use the “Read from CSV file” action to load all rows.
  2. Loop through rows — use a “For each” action.
  3. Set environment variables for each column value.
  4. Run the PowerShell script — use the “Run PowerShell Script” action pointing to your Fill-PDF.ps1.

Here’s how the “Run PowerShell Script” action should be configured:

textRun PowerShell Script Settings
PowerShell script file:     C:\PADPdfFiller\Fill-PDF.ps1
PowerShell script folder:   C:\PADPdfFiller\
Execution policy:           Bypass

Set the environment variables before calling the script using the “Set environment variable” action. For example, %PO_Number%, %PO_Date%, etc.

After the script runs, a new PDF appears in C:\PADPdfFiller\FilledPOs\ named PO-1001.pdf, PO-1002.pdf, and so on.

Security and Performance Considerations

  • Execution Policy — By default Windows restricts script execution. Use the Bypass policy in the PAD action, or sign your script with a code signing certificate.
  • File Permissions — Ensure the account running the desktop flow has write access to the output folder.
  • Performance — Each PDF is generated in a fraction of a second because no UI rendering is involved. This method scales easily to hundreds of PDFs.
  • DLL Trust — iTextSharp and BouncyCastle are well‑known open‑source libraries. Scan them with your antivirus before use.

Troubleshooting Common Issues

IssueLikely CauseSolution
“File not found” errorsIncorrect path in the scriptVerify that DLLs and PDF exist. Use absolute paths.
“Cannot find field”Field name mismatchRe‑run the discovery script and copy the exact name.
PDF opens blankThe script ran but no fields were filledCheck the $Data hashtable for missing or mistyped keys.
PAD action fails silentlyExecution policy blocks the scriptSet policy to Bypass in the action.
Read‑only property ignoredUsed wrong flag constantEnsure FF_READ_ONLY (value 1) is used.
PDF already open

If the PDF is open in another application (like Adobe Reader) when the script runs, it will fail with a “file in use” error. Close the file beforehand.

Final Thoughts

Abandoning UI automation for PDF forms is a clear win when you need speed, reliability, and ease of maintenance. A short PowerShell script that leverages iTextSharp can fill a form in milliseconds, and Power Automate Desktop provides the perfect orchestration layer to loop through rows of data.

This approach is not limited to purchase orders. You can apply it to any AcroForm‑based PDF: certificates, invoices, contracts, or regulatory forms. The same pattern also works in attended and unattended flows.

Give it a try on your next PDF‑heavy automation and see how much faster your process becomes.

References