我有一个Powershell脚本,可以将Office文档转换为PDF。我想多线程它,但不知道如何基于我所见过的其他例子。主脚本(OfficeToPDF.ps1)扫描文件列表,并为每个文件类型/办公应用程序调用单独的脚本(例如,对于.doc文件,调用WordToPDF.ps1进行转换)。主脚本一次将一个文件名传递给子脚本(我这样做有几个原因)。
下面是主脚本的一个示例:
$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()下面是主脚本调用的脚本(WordToPDF.ps1):
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()如有任何建议,我们将不胜感激。谢谢。
发布于 2015-12-23 06:16:53
我只是想评论一下,并将你链接到这个问题:Can PowerShell run commands in Parallel。然后我记下了这个问题的日期和答案,在PowerShell v3.0中,一些新功能可能更适合您。
这个问题涉及到PowerShell jobs的使用。它可以工作,但需要您跟上作业状态,因此可以添加一些额外的代码来管理。
PowerShell v3用基于Windows Workflow Foundation的workflow打开了更多的大门。有关这个新命令如何工作的基础知识的一篇好文章可以是found on Script Guy's blog here。你基本上可以调整你的代码,通过工作流来运行你的转换,它将并行地执行这一操作:
workflow foreachfile {
foreach -parallel ($f in $files) {
#Put your code here that does the work
}
}根据我所能找到的线程限制,它一次只能有5个线程。我不确定这有多准确,但blog post here noted the limitation。但是,由于Word和Excel的应用程序com对象可能会占用大量CPU资源,因此一次处理5个线程可能会很好地工作。
发布于 2015-12-23 11:51:43
我有一个多线程的powershell环境,用于在所有AD设备上扫描危害指示器-使用Gearman进行了625次线程。http://gearman.org
它是开源的,并且允许跨平台的选项。它通过服务器工作流进行线程处理,并通过Python运行。非常推荐给你--一个滥用powershell线程的人。这不是一个答案,而是一些我从未听说过的东西,但我每天都喜欢和使用它。向前传递它。为win开源:)
我以前也用过psjob,它们在达到一定程度之前都很棒。也许是我缺乏.net专业知识,但ps有一些令人反感的、微妙的内存细微差别,在大规模情况下可能会产生一些糟糕的影响。
https://stackoverflow.com/questions/34425112
复制相似问题