To convert HTML to PDF in PowerShell, let Microsoft Edge do the rendering. Edge ships with Windows 10 and 11, and its headless mode prints any HTML file to a PDF without opening a window:
Start-Process msedge.exe -ArgumentList '--headless', '--no-pdf-header-footer', '--print-to-pdf="C:\Reports\invoice.pdf"', '"C:\Reports\invoice.html"' -Wait
PowerShell has no built-in PDF cmdlet, so a browser engine is the most reliable route.
Below I build that line into a reusable function, turn ConvertTo-Html reports into PDFs, convert a folder and a URL, and cover Word as a fallback. The tests ran in PowerShell 7.6 and Windows PowerShell 5.1.
Find the Microsoft Edge path
msedge.exe isn’t in the PATH, so scripts that call it by name only work through Start-Process. Windows registers the full path under App Paths, which is the safest place to read it:
$key = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\msedge.exe'
$edge = (Get-ItemProperty -Path $key).'(default)'
$edge
"Edge found: $(Test-Path -Path $edge)"
Output:
C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe
Edge found: True
If you’d rather use Google Chrome, read the chrome.exe key the same way. Chrome accepted the exact same switches in my tests. You can also check a path with Test-Path before you start.
Convert an HTML file to PDF with headless Edge
My sample is a one-page invoice with a CSS @page rule for US Letter paper. The script builds the switch list, quotes every path, and waits for Edge to finish:
. .\HtmlPdf\PdfTools.ps1
$edge = (Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\msedge.exe').'(default)'
$html = (Resolve-Path -Path .\HtmlPdf\invoice-1042.html).Path
$pdf = [System.IO.Path]::ChangeExtension($html, '.pdf')
$temp = Join-Path -Path $env:TEMP -ChildPath 'edge-pdf'
$arguments = '--headless', '--disable-gpu', "--user-data-dir=`"$temp`"",
'--no-pdf-header-footer', "--print-to-pdf=`"$pdf`"", "`"$html`""
Start-Process -FilePath $edge -ArgumentList $arguments -Wait -WindowStyle Hidden
Get-PdfInfo -Path $pdf
Output:
invoice-1042.pdf: %PDF-1.4, 1 page(s), 8.5 x 11 in

The “bytes written to file” line comes from Edge itself. It shows up in an interactive console window but not in captured output, so don’t parse it.
Get-PdfInfo is a small helper I wrote for this post. It reads the %PDF header and each page’s MediaBox, which is the page size in points (72 per inch). Its code is in the function section below.
Here’s what each switch does:
--headlessrenders the page without a window.--user-data-dirpoints Edge at a separate temporary profile, so it never touches the Edge you have open.--no-pdf-header-footerremoves the browser’s date, title, file path and page number lines.--print-to-pdfsets the output file. Use a full path; a relative one is resolved by Edge, not by PowerShell.
The -Wait switch matters. Start-Process with -Wait returns only after Edge exits, and by then the PDF is on disk.
Remove the header and footer from the PDF
Leave out –no-pdf-header-footer and Edge stamps every page the way a manual print would. My test PDF got the local date and time, the page title, the full file:/// path and “1/1” in the margins.
That path can expose a user name, so I always add the switch.
If you name the PDF after the HTML file, get the file name from the path rather than reusing the full path.
Older scripts use –print-to-pdf-no-header instead. In Edge 156 that switch no longer removes anything, so update those scripts.
Set the page size, orientation and margins with CSS
Edge doesn’t take paper-size switches. It follows the CSS @page rule in the HTML, so the page layout lives in the file you convert:
@page { size: Letter landscape; margin: 0.5in }
Without that rule you get Edge’s default paper size. Use size: Letter for portrait, Legal for longer pages, and add page-break-before: always on any element that should start a new page.
Turn a ConvertTo-Html report into a PDF
The most common reason to do this is a report. ConvertTo-Html builds the HTML page, -Head adds the styles and the landscape rule, and the function below does the printing. This run is from Windows PowerShell 5.1:
. .\HtmlPdf\PdfTools.ps1
$sales = @(
[pscustomobject]@{ Office = 'Austin'; Rep = 'Maria Lopez'; Deals = 14; Revenue = 48250 }
[pscustomobject]@{ Office = 'Denver'; Rep = 'Tom Baker'; Deals = 9; Revenue = 31900 }
[pscustomobject]@{ Office = 'Seattle'; Rep = 'Dana Reyes'; Deals = 12; Revenue = 44175 }
[pscustomobject]@{ Office = 'Boston'; Rep = 'Alex Wilber'; Deals = 7; Revenue = 26480 }
)
$head = @'
<meta charset="utf-8"><title>Q3 2026 sales</title>
<style>
@page { size: Letter landscape; margin: 0.5in }
body { font-family: 'Segoe UI', Arial, sans-serif }
table { border-collapse: collapse; width: 100% }
th { background: #1a4f8b; color: #fff; text-align: left }
th, td { border: 1px solid #ccc; padding: 6px 10px }
</style>
'@
$html = Join-Path -Path (Resolve-Path .\HtmlPdf).Path -ChildPath 'sales-q3-2026.html'
$sales |
Select-Object Office, Rep, Deals, @{ n = 'Revenue'; e = { '${0:N2}' -f $_.Revenue } } |
ConvertTo-Html -Head $head -PreContent '<h1>Q3 2026 sales by office</h1>' |
Set-Content -Path $html -Encoding UTF8
ConvertTo-PdfEdge -HtmlPath $html -PdfPath ($html -replace '\.html$', '.pdf')
Get-PdfInfo -Path ($html -replace '\.html$', '.pdf')
Output:
sales-q3-2026.pdf: %PDF-1.4, 1 page(s), 11 x 8.5 in
