As the Microsoft support for Publisher ends in October and as someone whose family utilizes and has hundreds of .pub files, the other night I reviewed the out of the box Microsoft provided .PUB to .PDF version as a base:
and created a new PowerShell script which converts the .pub → .pdf (Publisher) → .rtf → .docx (Word) either file by file or via batch format by providing the proper filter:
Full script is below for educational purposes just copy and paste and save to the location of your choosing:
<#
Convert-PubFileToRTFModal.ps1
.SYNOPSIS
Converts .pub → .pdf (Publisher) → .rtf + .docx (Word)
with automatic Publisher kill‑and‑restart when modal dialogs appear.
.DESCRIPTION
This version:
• Removes ALL UIAutomation dialog handling
• Detects modal dialog COM lock
• Kills Publisher immediately when locked
• Restarts Publisher for each retry
• Retries each file once
• Skips files that remain locked
.EXAMPLES
Run with the following filters from PowerShell Command Line:
If needed set proper execution policies:
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
.EXAMPLE
./Convert-PubFileToRTFModal.ps1 -Filter "C:\Documents\MyFile.pub"
Converts the specified Publisher file to PDF to RTF to WORD format.
.EXAMPLE
./Convert-PubFileToRTFModal.ps1 -Filter "*.pub"
Converts all Publisher files in the current directory to PDF to RTF to WORD format.
.EXAMPLE
./Convert-PubFileToRTFModal.ps1 -Filter "*.pub" -Recurse
Converts all Publisher files in the current directory and all subdirectories to PDF to RTF to WORD format.
KMO 8/20/2026 used Microsoft .PUB to .PDF version as base:
https://download.microsoft.com/download/3e67cd40-2334-4c46-a0c9-30bd43eebb3c/Convert-PubFileToPDF.ps1
Script was only utilized with Windows 11 Home Edition
#>
param(
[Parameter(Mandatory=$true)]
[string]$Filter,
[switch]$Recurse
)
function Kill-Publisher {
Write-Warning "Killing all Publisher processes..."
Get-Process -Name "MSPUB" -ErrorAction SilentlyContinue | Stop-Process -Force -ErrorAction SilentlyContinue
Start-Sleep -Seconds 1
}
function Start-Publisher {
try { return (New-Object -ComObject Publisher.Application) }
catch {
Write-Warning "Publisher cannot start."
return $null
}
}
function Start-Word {
try { return (New-Object -ComObject Word.Application) }
catch {
Write-Warning "Word cannot start."
return $null
}
}
function Export-PubToPdf {
param(
[string]$PubPath,
[string]$PdfPath
)
$app = Start-Publisher
if (-not $app) { return $false }
try {
$doc = $app.Open($PubPath)
}
catch {
Write-Warning "Open() failed for: $PubPath -> $_"
Kill-Publisher
return $false
}
if (-not $doc) {
Write-Warning "Publisher returned null document: $PubPath"
Kill-Publisher
return $false
}
try {
$doc.ExportAsFixedFormat(
[Microsoft.Office.Interop.Publisher.PbFixedFormatType]::pbFixedFormatTypePDF,
$PdfPath
)
Write-Output "Saved PDF: $PdfPath"
}
catch {
Write-Warning "PDF export failed for: $PubPath -> $_"
Kill-Publisher
return $false
}
try { $doc.Close() } catch { Kill-Publisher }
try { $app.Quit() } catch { Kill-Publisher }
return $true
}
function Convert-PdfToRtfDocx {
param(
[string]$PdfPath,
[string]$RtfPath,
[string]$DocxPath
)
if (-not (Test-Path $PdfPath)) {
Write-Warning "PDF not found for Word conversion: $PdfPath"
return $false
}
$word = Start-Word
if (-not $word) { return $false }
$word.Visible = $false
try {
$doc = $word.Documents.Open($PdfPath)
}
catch {
Write-Warning "Word cannot open PDF: $PdfPath -> $_"
try { $word.Quit() } catch {}
return $false
}
if (-not $doc) {
Write-Warning "Word returned null document for: $PdfPath"
try { $word.Quit() } catch {}
return $false
}
$ok = $true
try {
$doc.SaveAs([ref]$RtfPath, [ref][int][Microsoft.Office.Interop.Word.WdSaveFormat]::wdFormatRTF)
Write-Output "Saved RTF: $RtfPath"
}
catch {
Write-Warning "RTF save failed for: $PdfPath -> $_"
$ok = $false
}
try {
$doc.SaveAs([ref]$DocxPath, [ref][int][Microsoft.Office.Interop.Word.WdSaveFormat]::wdFormatXMLDocument)
Write-Output "Saved DOCX: $DocxPath"
}
catch {
Write-Warning "DOCX save failed for: $PdfPath -> $_"
$ok = $false
}
try { $doc.Close() } catch {}
try { $word.Quit() } catch {}
return $ok
}
function Convert-OneFile {
param([string]$PubPath)
$base = [System.IO.Path]::Combine(
[System.IO.Path]::GetDirectoryName($PubPath),
[System.IO.Path]::GetFileNameWithoutExtension($PubPath)
)
$pdf = "$base.pdf"
$rtf = "$base.rtf"
$docx = "$base.docx"
Write-Output "Converting: $PubPath"
# --- FIRST ATTEMPT ---
if (Export-PubToPdf -PubPath $PubPath -PdfPath $pdf) {
if (Convert-PdfToRtfDocx -PdfPath $pdf -RtfPath $rtf -DocxPath $docx) {
return $true
}
}
Write-Warning "First attempt failed. Retrying with clean Publisher restart..."
Kill-Publisher
# --- SECOND ATTEMPT ---
if (Export-PubToPdf -PubPath $PubPath -PdfPath $pdf) {
if (Convert-PdfToRtfDocx -PdfPath $pdf -RtfPath $rtf -DocxPath $docx) {
return $true
}
}
Write-Warning "Skipping file (Publisher remained locked): $PubPath"
return $false
}
# Validate filter
if (-not ($Filter -like "*.pub")) {
Write-Warning "Filter must specify .pub files."
exit 1
}
$files = Get-ChildItem -File -Recurse:$Recurse -Filter $Filter
if (-not $files) {
Write-Warning "No .pub files found."
exit 1
}
$success = 0
$fail = 0
foreach ($file in $files) {
if (Convert-OneFile -PubPath $file.FullName) { $success++ }
else { $fail++ }
}
Write-Output "Completed: $success succeeded, $fail failed."
No comments:
Post a Comment