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.
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_Number | PO_Date | Vendor | Part_Number | Qty | Unit_Price | Total |
|---|---|---|---|---|---|---|
| PO-1001 | 2026-06-03 | Acme Supplies | A-1234 | 10 | 25.50 | 255.00 |
| PO-1002 | 2026-06-03 | Beta Components | B-5678 | 25 | 12.00 | 300.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.
- Go to the iTextSharp NuGet page and download the package.
- Go to the BouncyCastle NuGet page and download the package.
- In Windows Explorer, rename both
.nupkgfiles to.zipand extract them. - Inside each extracted folder locate the
.dllfiles:itextsharp.dllBouncyCastle.Crypto.dll
- 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.
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).
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()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:
- Read CSV file — use the “Read from CSV file” action to load all rows.
- Loop through rows — use a “For each” action.
- Set environment variables for each column value.
- 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:
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
Bypasspolicy 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
| Issue | Likely Cause | Solution |
|---|---|---|
| “File not found” errors | Incorrect path in the script | Verify that DLLs and PDF exist. Use absolute paths. |
| “Cannot find field” | Field name mismatch | Re‑run the discovery script and copy the exact name. |
| PDF opens blank | The script ran but no fields were filled | Check the $Data hashtable for missing or mistyped keys. |
| PAD action fails silently | Execution policy blocks the script | Set policy to Bypass in the action. |
| Read‑only property ignored | Used wrong flag constant | Ensure FF_READ_ONLY (value 1) is used. |
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
- Original article by Matthew Devaney: Fill PDF Form Fields 5x Faster With Power Automate Desktop
- Microsoft documentation on the Run PowerShell Script action: PowerShell actions in Power Automate Desktop