[英]Powershell multithreading
我有一個Powershell腳本,可以將Office文檔轉換為PDF。 我想對其進行多線程處理,但無法根據我所看到的其他示例弄清楚該如何做。 主腳本(OfficeToPDF.ps1)掃描文件列表,並為每種文件類型/辦公應用程序調用單獨的腳本(例如,.doc文件稱為WordToPDF.ps1進行轉換)。 主腳本一次將1個文件名傳遞給子腳本(出於兩個原因,我這樣做了)。
這是主要腳本的示例:
$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()
任何建議,將不勝感激。 謝謝。
我只是要發表評論並將您鏈接到這個問題: PowerShell可以在Parallel中運行命令 。 然后,我記下了該問題的日期和答案,在PowerShell v3.0中,有些新功能可能對您更好。
問題超出了使用PowerShell作業的范圍 。 可以正常工作,但需要跟上工作狀態,因此可以添加一些額外的代碼來管理。
PowerShell v3通過基於Windows Workflow Foundation的workflow
為您打開了更多的大門。 可以在Script Guy的博客上找到有關此新命令如何工作的基礎知識的好文章。 您基本上可以調整代碼以通過工作流運行轉換,它將並行執行此操作:
workflow foreachfile {
foreach -parallel ($f in $files) {
#Put your code here that does the work
}
}
從我可以找到的線程限制中,一次有5個線程。 我不確定這有多准確,但是這里的博客文章指出了限制 。 但是,由於Word和Excel的Application com對象可能占用大量CPU,因此一次執行5個線程可能會很好地工作。
我有一個多線程Powershell環境,用於顯示在所有AD設備上進行危害掃描的指標-使用Gearman進行625次線程掃描。 http://gearman.org
它是開源的,允許跨平台使用。 它與服務器工作程序流配合並通過Python運行。 真正由您極力推薦-濫用Powershell線程的人。 這不是一個答案,而是我從未聽說過的東西,但每天都在愛和用。 向前傳遞。 開源的勝利:)
我以前也使用過psjobs,並且它們在達到一定數量級之前都很棒。 也許是因為我缺乏.net專業知識,但是ps具有一些古怪的微妙記憶細微差別,在很大程度上可以產生一些討厭的效果。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.