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() } }