title: Powershell multithreading
body: <p>I have a Powershell script that converts Office documents to PDF. I would like to multithread it, but cannot figure out how based on other examples I have seen. The main script (OfficeToPDF.ps1) scans through a list of files and calls separate scripts for each file type/office application (ex. for .doc files WordToPDF.ps1 is called to convert). The main script passes 1 file name at a time to the child script ( I did this for a couple of reasons).</p>
  
  <p>Here is an example of the main script:</p>
  
  <pre><code>    $documents_path = "C:\Documents\Test_Docs"
      $pdf_out_path = "C:\Documents\Converted_PDFs"
      $failed_path = "C:\Documents\Failed_to_Convert"
  
      # Sets the root directory of this script
      $PSScriptRoot = Split-Path -parent $MyInvocation.MyCommand.Definition
  
      $date = Get-Date -Format "MM_dd_yyyy"
      $Logfile = "$PSScriptRoot\logs\OfficeToTiff_$Date.log"
  
      $word2PDF = "$PSScriptRoot\WordToPDF.ps1"
      $arguments = "'$documents_path'", "'$pdf_out_path'", "'$Logfile'"
  
      # Function to write to log file
      Function LogWrite
      {
         Param ([string]$logstring)
         $time = Get-Date -Format "hh:mm:ss:fff"
  
         Add-content $Logfile -value "$date $time $logstring"
      }
  
  
  ################################################################################
  # Word to PDF                                                                  #
  ################################################################################
  
      LogWrite "*** BEGIN CONVERSION FROM DOC, DOCX, RTF, TXT, HTM, HTML TO PDF ***"
  
      Get-ChildItem -Path $documents_path\* -Include *.docx, *.doc, *.rtf, *.txt, *.htm? -recurse | ForEach-Object {
  
              $original_document = "$($_.FullName)"
  
              # Verifies that a document exists before calling the convert script
              If ($original_document -ne $null)
              {
  
                  Invoke-Expression "$word2PDF $arguments"
  
                  #checks to see if document was successfully converted and deleted.  If not, doc is moved to another directory
                  If(Test-Path -path $original_document)
                  {
                  Move-Item $original_document $failed_path
                  }
              }
           }
  
      $original_document = $null
  
      [gc]::collect()
      [gc]::WaitForPendingFinalizers()
  </code></pre>
  
  <p>Here is the script (WordToPDF.ps1) that is called by the main script:</p>
  
  <pre><code>Param($documents, $pdf_out_path, $Logfile)
  
  # Function to write to the log file
  Function LogWrite
  {
     Param ([string]$logstring)
     $time = Get-Date -Format "hh:mm:ss:fff"
  
     Add-content $Logfile -value "$date $time $logstring"
  }
  
  $word_app = New-Object -ComObject Word.Application
  
  $document = $word_app.Documents.Open($_.FullName)
  $original_document = "$($_.FullName)"
  
  # Creates the output file name with path
  $pdf_document = "$($pdf_out_path)\$($_.BaseName).pdf"
  
  LogWrite "Converting: $original_document to $pdf_document"
  $document.SaveAs([ref] $pdf_document, [ref] 17)
  $document.Close()
  
  # Deletes the original document after it has been converted
  Remove-Item $original_document
  LogWrite "Deleting: $original_document"
  
  $word_app.Quit()
  </code></pre>
  
  <p>Any suggestions would be appreciated.
  Thanks.</p>