首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Powershell多线程

Powershell多线程
EN

Stack Overflow用户
提问于 2015-12-23 05:57:46
回答 2查看 1.3K关注 0票数 0

我有一个Powershell脚本,可以将Office文档转换为PDF。我想多线程它,但不知道如何基于我所见过的其他例子。主脚本(OfficeToPDF.ps1)扫描文件列表,并为每个文件类型/办公应用程序调用单独的脚本(例如,对于.doc文件,调用WordToPDF.ps1进行转换)。主脚本一次将一个文件名传递给子脚本(我这样做有几个原因)。

下面是主脚本的一个示例:

代码语言:javascript
复制
    $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):

代码语言:javascript
复制
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()

如有任何建议,我们将不胜感激。谢谢。

EN

回答 2

Stack Overflow用户

发布于 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。你基本上可以调整你的代码,通过工作流来运行你的转换,它将并行地执行这一操作:

代码语言:javascript
复制
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个线程可能会很好地工作。

票数 1
EN

Stack Overflow用户

发布于 2015-12-23 11:51:43

我有一个多线程的powershell环境,用于在所有AD设备上扫描危害指示器-使用Gearman进行了625次线程。http://gearman.org

它是开源的,并且允许跨平台的选项。它通过服务器工作流进行线程处理,并通过Python运行。非常推荐给你--一个滥用powershell线程的人。这不是一个答案,而是一些我从未听说过的东西,但我每天都喜欢和使用它。向前传递它。为win开源:)

我以前也用过psjob,它们在达到一定程度之前都很棒。也许是我缺乏.net专业知识,但ps有一些令人反感的、微妙的内存细微差别,在大规模情况下可能会产生一些糟糕的影响。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34425112

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档