Last active
April 28, 2026 21:34
-
-
Save StartAutomating/d1d8d2e5fe835ea30bcbacb0b00308b1 to your computer and use it in GitHub Desktop.
Gist Convert Word Documents to Different Formats
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| function Convert-Word { | |
| <# | |
| .SYNOPSIS | |
| Converts Word Documents | |
| .DESCRIPTION | |
| Converts Word Documents to a few formats: | |
| * `docx` | |
| * `doct` | |
| * `html` | |
| * `pdf` | |
| * `rtf` | |
| * `xml` | |
| * `xps` | |
| .NOTES | |
| This uses the Word COM Object Model for conversion. | |
| This requires Word to be installed. | |
| Some documents may not open due to trust settings. | |
| .EXAMPLE | |
| Get-ChildItem ./OldWord/ -File | | |
| Where-Object Extension -in '.rtf', '.doc' | | |
| Convert-Word | |
| #> | |
| param( | |
| # The file path containing word documents | |
| [Parameter(Mandatory,ValueFromPipelineByPropertyName)] | |
| [Alias('Fullname')] | |
| [string] | |
| $FilePath, | |
| # The output document type. | |
| [Alias('docx', 'doct', 'html', 'pdf', 'rtf', 'xml', 'xps')] | |
| [string] | |
| $To = 'docx' | |
| ) | |
| begin { | |
| # Try to open word | |
| $wordApp = New-Object -ComObject Word.Application | |
| if (-not $wordApp) { throw "Word not installed"} | |
| # and create a queue to hold our files | |
| $convertQueue = [Collections.Queue]::new() | |
| } | |
| process { | |
| # Get all of the files | |
| foreach ($fileInfo in Get-Item -Path $FilePath) { | |
| # check their extension | |
| if ($fileInfo.Extension -notin '.rtf', '.doc','.docx') { | |
| # and warn if it's not a file we can convert. | |
| Write-Warning "$($fileInfo.FullName) is not a word document" | |
| continue | |
| } | |
| # Otherwise, add it to the queue. | |
| $convertQueue.Enqueue($fileInfo) | |
| } | |
| } | |
| end { | |
| # Turn our queue into an array | |
| $queue = $convertQueue.ToArray() | |
| # and prepare our progress bars | |
| $progress = @{id=Get-Random;Activity='Converting Word'} | |
| # Go over each document | |
| for ($docNumber = 0 ; $docNumber -lt $queue.Count; $docNumber++) { | |
| # get the file | |
| $fileInfo = $queue[$docNumber] | |
| # adjust our progress bar | |
| $progress.PercentComplete = $docNumber / $queue.Count * 100 | |
| $progress.Status = $fileInfo.Fullname | |
| # and write progress. | |
| Write-Progress @progress | |
| # Figure out where the file is going to go. | |
| $destination = | |
| $fileInfo.FullName.Substring( | |
| 0, $fileInfo.FullName.Length - $fileInfo.Extension.Length | |
| ) + ".$($to.ToLower())" | |
| # Warn if the files are the same | |
| if ($destination -eq $fileInfo.FullName) { | |
| Write-Warning "Will not overwrite $($fileInfo.Fullname)" | |
| continue | |
| } | |
| try { | |
| # Try to open the file | |
| $openedFile = $wordApp.Documents.Open($fileInfo.FullName) | |
| } catch { | |
| # and error out and continue if we cannot | |
| Write-Error "Could not open '$($fileInfo.Fullname)': $_" | |
| continue | |
| } | |
| # We have to use an old enum to convert to different file formats | |
| # [See This Reference](https://learn.microsoft.com/en-us/office/vba/api/word.wdsaveformat) | |
| # Currently not allowing anywhere near the whole list, for the sake of sanity and security. | |
| switch ($to) { | |
| docx { $openedFile.SaveAs($destination,[ref]16) } | |
| doct { $openedFile.SaveAs($destination,[ref]14) } | |
| html { $openedFile.SaveAs($destination,[ref]8) } | |
| pdf { $openedFile.SaveAs($destination,[ref]17) } | |
| rtf { $openedFile.SaveAs($destination,[ref]6) } | |
| txt { $openedFile.SaveAs($destination,[ref]5) } | |
| xml { $openedFile.SaveAs($destination,[ref]11) } | |
| xps { $openedFile.SaveAs($destination,[ref]18) } | |
| } | |
| # Close the file we've opened. | |
| $openedFile.Close() | |
| # and output the file we've exported. | |
| Get-Item -LiteralPath $destination | |
| } | |
| # Make sure we complete our progress bar so it doesn't leave something on the screen | |
| $progress.Remove('PercentComplete') | |
| $progress.Completed = $true | |
| Write-Progress @progress | |
| # and quit word, so we don't have an open `winword.exe` hanging around. | |
| $wordApp.Quit() | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment