Monday, August 24, 2026

Publisher PowerShell - Converts .pub to .pdf to .rtf to .docx

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:

https://download.microsoft.com/download/3e67cd40-2334-4c46-a0c9-30bd43eebb3c/Convert-PubFileToPDF.ps1
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