Convertir plusieurs documents Word en PDF via PowerShell / How to convert multiple Word documents into a PDF document in a row with PowerShell
[MAJ 06/03/2017] Les versions les plus récentes de Word permettent de convertir (et également d'ouvrir) un document Word en PDF (via le menu "File >> Save As" pour la conversion). Cette fonctionnalité , quoique très pratique, ne permet que de convertir un document à la fois (après avoir ouvert le document dans l'application Word). Dans ma vie de PFE, je suis amené à écrire et à mettre à jour beaucoup de documentations (formations, rapports à destination de clients, documentations internes, compte-rendus de réunions, ...) et dans certains je dois les envoyer au format PDF. Vous imaginez bien que dans le cas de plusieurs fichiers à convertir je ne vais pas les ouvrir 1 par 1 dans Word. Au lieu de cela j'ai écrit une petit script PowerShell que j'ai décidé de vous partager ici.
Ce script est aussi disponible dans le TechNet Script Center : https://gallery.technet.microsoft.com/Convert-multiple-word-7660a791
[Updated 03/06/2017] The most recent versions of Word give you the opportunity to convert (and also to open) a Word document into a PDF document (via the "File >> Save As" Menu for the conversion feature). This feature, though very convenient, can only convert one document at a time (after opening the document in the Word application). In my PFE life, I write and update many documentations (WorkShops, customer reports, internal documents, minutes of meetings, ...) and sometimes I have to send them in the PDF Format. You can imagine that in the case of multiple files to convert I will not open them one by one in Word. Instead I wrote a small PowerShell script that I decided to share with you here.
#requires -Version 4
#region function definitions
Function Remove-Ref
{
param
(
[parameter(Mandatory = $true, HelpMessage = 'Please specify a reference')]
[Object]$ref
)
<#
.SYNOPSIS
Releases a COM Object
.DESCRIPTION
Releases a COM Object
.PARAMETER ref
The COM Object to release
.EXAMPLE
$Word=new-object -ComObject "Word.Application"
...
Remove-Ref($Word)
#>
$null = Remove-Variable -Name $ref -ErrorAction SilentlyContinue
while ([Runtime.InteropServices.Marshal]::ReleaseComObject([__ComObject]$ref) -gt 0)
{
}
[GC]::Collect()
[GC]::WaitForPendingFinalizers()
}
Function ConvertTo-PDF
{
<#
.SYNOPSIS
Convert a Word document into a PDF document
.DESCRIPTION
Convert a Word document into a PDF document
.PARAMETER FullName
The Word document to convert specified by its full name or by a System.IO.FileInfo object
.PARAMETER Force
A switch to specify if we overwrite the PDF document even if it is newer than that the Word document
.PARAMETER Visible
A switch to specify if the Word application will be visible during the processing
.EXAMPLE
Get-ChildItem "*.docx" | ConvertTo-PDF -Verbose
Will convert all word documents into PDF documents but only if the Word document is newer than the related PDF document (if any). The verbose mode is enabled
.EXAMPLE
Get-ChildItem "*.docx" | ConvertTo-PDF -Force
Will convert all word documents into PDF documents even if the PDF document is newer than the original Word document
.EXAMPLE
ConvertTo-PDF -FullName "c:\datasheet_FR-fr.docx", "c:\datasheet_en_US.docx" -Force
Will convert two word documents into PDF documents even if the PDF document is newer than the original Word document
#>
Param(
#The Word Document to convert
[Parameter(Mandatory = $true,HelpMessage = 'Please enter the full path of a Word Document', ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
[ValidateScript({
(Test-Path -Path $_ -PathType Leaf) -and ($_ -match '\.docx?$')
})]
[alias('Source', 'WordDocument', 'Document')]
[string[]]$FullName,
#To overwrite the previously generated PDF files."
[switch]$Force,
#To display the Word application
[switch]$Visible
)
begin
{
#Loading Word Properties
$null = Add-Type -AssemblyName Microsoft.Office.Interop.Word
#Static value for the PDF format (for saving)
$wdFormatPDF = [Microsoft.Office.Interop.Word.WdSaveFormat]::wdFormatPDF
#Static value for not saving changes
$wdDoNotSaveChanges = [Microsoft.Office.Interop.Word.WdSaveOptions]::wdDoNotSaveChanges
#Constant Definitions
$ConfirmConversion = $false
$ReadOnly = $true
Write-Verbose -Message 'Running the Word application ...'
#Opening the Word Application
$Word = New-Object -ComObject 'Word.Application'
$Word.Visible = $Visible
$Word.Application.DisplayAlerts = $false
}
process
{
#For all files passed as argument outside a pipeline context
Foreach ($CurrentFullName in $FullName)
{
$CurrentFullName = Get-Item -Path $CurrentFullName
#Getting the fullname of the processed presentation
$SourceWordDocumentFullName = $CurrentFullName.FullName
#Getting the name of the processed presentation
$SourceWordDocumentName = $CurrentFullName.Name
#Getting the final PDF full name (same directory and name that the Word document)
$TargetPDFDocumentFullName = $($SourceWordDocumentFullName) -replace '\.docx?$', '.pdf'
#Getting the write time of the word document
$SourceWordDocumentTimeWritten = $(Get-Item -Path $SourceWordDocumentFullName).LastWriteTime
#Getting if -Force was specified or if the PDF doesn't exist or if the Word document is newer that a previously generated PDF Document.
If (($Force) -or (!(Test-Path -Path $TargetPDFDocumentFullName)) -or ($(Get-Item -Path $TargetPDFDocumentFullName).LastWriteTime -lt $SourceWordDocumentTimeWritten))
{
#If -Force was specified
If ($Force)
{
Write-Verbose -Message ('Forcing {0} ...' -f $SourceWordDocumentFullName)
}
#If the PDF doesn't exist
ElseIf (!(Test-Path -Path $TargetPDFDocumentFullName))
{
Write-Verbose -Message ('Processing {0} ...' -f $SourceWordDocumentFullName)
}
#If the Word document is newer that a previously generated PDF Document.
ElseIf ($(Get-Item -Path $TargetPDFDocumentFullName).LastWriteTime -lt $SourceWordDocumentTimeWritten)
{
Write-Verbose -Message ('Updating {0} ...' -f $SourceWordDocumentFullName)
}
Write-Verbose -Message 'Opening the Word document ...'
$OpenDoc = $Word.Documents.OpenNoRepairDialog($SourceWordDocumentFullName, $ConfirmConversion, $ReadOnly)
Write-Verbose -Message 'Saving the PDF document ...'
$OpenDoc.SaveAs($TargetPDFDocumentFullName, $wdFormatPDF)
Write-Verbose -Message 'Closing the Word document ...'
$OpenDoc.Close($wdDoNotSaveChanges)
Write-Host -Object ("The PDF file is available at : '{0}'" -f $TargetPDFDocumentFullName)
Remove-Ref -ref ($OpenDoc)
}
else
{
Write-Host -Object ("Skipping '{0}' because it is up-to-date`r`nUse -force to overwrite previously generated PDF file" -f $SourceWordDocumentName) -ForegroundColor Yellow
}
}
}
end
{
Write-Verbose -Message 'Exiting the Word application ...'
$null = $Word.Quit()
Remove-Ref -ref ($Word)
}
}
#endregion
Clear-Host
# To get the directory of this script
$CurrentDir = Split-Path -Path $MyInvocation.MyCommand.Path -Parent
Get-ChildItem -Path "C:\Users\lavanack\Documents\Comptes\Mairie de Lille\PowerShell - April 2016\Labs" -Filter '*.docx' | ConvertTo-PDF -Verbose -Force -Visible
#ConvertTo-PDF -Source "$CurrentDir\datasheet_FR-fr.docx", "$CurrentDir\datasheet_en_US.docx" -Force -Verbose
The script file is also available at the TechNet Script Center repository, at: https://gallery.technet.microsoft.com/Convert-multiple-word-7660a791
Laurent