-
-
Save mp4096/1a2279ec7b3dfec659f58e378ddd9aee to your computer and use it in GitHub Desktop.
# Batch convert all .ppt/.pptx files encountered in folder and all its subfolders | |
# The produced PDF files are stored in the invocation folder | |
# | |
# Adapted from http://stackoverflow.com/questions/16534292/basic-powershell-batch-convert-word-docx-to-pdf | |
# Thanks to MFT, takabanana, ComFreek | |
# | |
# If PowerShell exits with an error, check if unsigned scripts are allowed in your system. | |
# You can allow them by calling PowerShell as an Administrator and typing | |
# ``` | |
# Set-ExecutionPolicy Unrestricted | |
# ``` | |
# Get invocation path | |
$curr_path = Split-Path -parent $MyInvocation.MyCommand.Path | |
# Create a PowerPoint object | |
$ppt_app = New-Object -ComObject PowerPoint.Application | |
# Get all objects of type .ppt? in $curr_path and its subfolders | |
Get-ChildItem -Path $curr_path -Recurse -Filter *.ppt? | ForEach-Object { | |
Write-Host "Processing" $_.FullName "..." | |
# Open it in PowerPoint | |
$document = $ppt_app.Presentations.Open($_.FullName) | |
# Create a name for the PDF document; they are stored in the invocation folder! | |
# If you want them to be created locally in the folders containing the source PowerPoint file, replace $curr_path with $_.DirectoryName | |
$pdf_filename = "$($curr_path)\$($_.BaseName).pdf" | |
# Save as PDF -- 17 is the literal value of `wdFormatPDF` | |
$opt= [Microsoft.Office.Interop.PowerPoint.PpSaveAsFileType]::ppSaveAsPDF | |
$document.SaveAs($pdf_filename, $opt) | |
# Close PowerPoint file | |
$document.Close() | |
} | |
# Exit and release the PowerPoint object | |
$ppt_app.Quit() | |
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($ppt_app) |
Trying this on Windows 10 Enterprise, get the following errors:
+ $pdf_filename = $($_.DirectoryName)($_.BaseName).pdf?
Unexpected token '(' in expression or statement.
+ ... pt= [Microsoft.Office.Interop.PowerPoint.PpSaveAsFileType]ppSaveAsPDF
Unexpected token 'ppSaveAsPDF' in expression or statement.
+ [System.Runtime.Interopservices.Marshal]ReleaseComObject($pptx_app)
Unexpected token 'ReleaseComObject' in expression or statement.
+ CategoryInfo : ParserError: (:) [], ParseException
+ FullyQualifiedErrorId : UnexpectedToken
I am a complete greenhorn when it comes to powershell scripts and am currently trying to debug this myself, but any help would be highly appreciated!
Edit: Chat GPT to the rescue, had to change the following:
- added the pipeline operator (|) to connect the output of Get-ChildItem to ForEach-Object.
- Corrected the value of $opt by changing 17 to 32, which is the literal value of ppSaveAsPDF
- Added the :: syntax to access the ppSaveAsPDF enumeration value, and also added the :: syntax to access the ReleaseComObject method.
This however ran on all files in the directory, here is the ultimate script I ended up using as I wanted to have the files copied into another folder:
# Copy all files from source folder to destination folder
$source_dir = "C:\Users\Username\Desktop\Additional Stuff Extra\"
$dest_dir = "C:\Users\Username\Desktop\Additional Stuff Extra PDF\"
Get-ChildItem $source_dir -Include *.ppt,*.pptx -Recurse | ForEach-Object {
# Create subdirectory
$subdir_destination = Join-Path $dest_dir $_.Directory.Name
if (!(Test-Path $subdir_destination)) {
New-Item -ItemType Directory -Force -Path $subdir_destination
Write-Output "Created subdirectory: $subdir_destination"
}
if ($_.Extension -eq ".ppt" -or $_.Extension -eq ".pptx") {
$pdf_filename = [System.IO.Path]::ChangeExtension($_.Name, ".pdf")
$pdf_path = Join-Path $subdir_destination $pdf_filename
Add-Type -AssemblyName Office
$powerpoint = New-Object -ComObject PowerPoint.Application
$powerpoint.Visible = [Microsoft.Office.Core.MsoTriState]::msoTrue
$presentation = $powerpoint.Presentations.Open($_.FullName)
$presentation.SaveAs($pdf_path, [Microsoft.Office.Interop.PowerPoint.PpSaveAsFileType]::ppSaveAsPDF)
$presentation.Close()
$powerpoint.Quit()
Write-Output "Converted $($_.FullName) to $pdf_path"
}
else {
$destination = Join-Path $subdir_destination $_.Name
Copy-Item $_.FullName $destination -Force
Write-Output "Copied $($_.FullName) to $destination"
}
}
When trying to run directly from the command line without creating a script and changing system settings, I had to change $curr_path = Split-Path -parent $MyInvocation.MyCommand.Path
to $curr_path = Get-Location
It works!
I've tested it in Powershell (execute as administrator) using Windows 10.
It shows an error, but I executed the recommended line:
Set-ExecutionPolicy Unrestricted
After that, I executed the script again! It worked!
Works well with Windows 10 Home edition.