是否可以并行呼叫 powershell 函式或腳本多次并在繼續之前等待資料回傳?我已經在 Linux 中做到了這一點,我的偽代碼更像是在 linux 中的例子。
假設我們有一個名為“Get-OSRebootDates”的函式,它將最近的重啟作為結果字串回傳。我可以并行運行而不是串行運行嗎?
普通串行方式
$Result = @()
ForEach ($pcname in $pclistarray) {
$Result = Get-OSRebootDates -Target $pcname
# call it one at a time and wait before moving on to the next
}
# then do something with data
我想并行執行的偽代碼:
$Result = @()
$($Result = Get-OSRebootDates -Target $pcname1) &
$($Result = Get-OSRebootDates -Target $pcname2) &
$($Result = Get-OSRebootDates -Target $pcname3) &
$($Result = Get-OSRebootDates -Target $pcname4) &
Wait
# then do something with the data
僅供參考示例函式
Function Get-OSRebootDates {
# Summary: Search Application log for recent reboots in hours (e.g. $RangeNegHours -> -340) (this search is fast)
# Params: Target is howt, Range is how far to look back
Param(
[Parameter(Mandatory = $true)]$Target,
[Parameter(Mandatory = $false)]$RangeNegHours = -8760 # default 1 year
)
$filters = @{}
$filters.Add("StartTime", ((Get-Date).AddHours([int]$RangeNegHours)))
$filters.Add("EndTime", (Get-Date))
$filters.Add("LogName", "System")
$filters.Add("ID", 6005) #6005 started, #6006 shutdown
$filters.Add("providername", '*EventLog*')
$filters.Add("level", 4)
$RebootDates = [string]::Empty
Try {
$LogRaw = Get-WinEvent -ErrorAction Stop -FilterHashtable $filters -MaxEvents 2500000 -ComputerName $Target | select-object id, machinename, timecreated, message, LevelDisplayName, ProviderName
}
Catch {
Write-Host ("Something went wrong with [" $MyInvocation.MyCommand "] for " $Target " ..") -ForegroundColor Red
start-sleep -seconds 4
return $RebootDates
}
$Count = 0
ForEach ($Item in $LogRaw) {
If ([string]$Item.TimeCreated) {
$RebootDates = $RebootDates [string]$Item.TimeCreated "`n"
$Count = 1
If ($Count -gt 5) {
break;
}
}
}
Return [string]$RebootDates
}
uj5u.com熱心網友回復:
tl;dr關于您的Normal 串行方法, =在 aSystem.Array上使用效率非常低,因為arrays是固定大小的集合,PowerShell 必須在回圈的每次迭代中重新創建它foreach。請參閱此問答以獲得更好的解釋。
這應該是您轉到普通串行方法的方法,或者您可以使用System.Collections.Generic.List<T>或System.Collections.ArrayList。
$Result = ForEach ($pcname in $pclistarray) {
Get-OSRebootDates -Target $pcname
# call it one at a time and wait before moving on to the next
}
關于您的主要問題,如何并行運行函式并等待輸出,首先,根據我的個人經驗,Get-WinEvent我在使用時看到了更好(更快)的結果:
Invoke-Command -ComputerName server01 -ScriptBlock { Get-WinEvent .... }
比這樣做:
Get-WinEvent .... -ComputerName server01
此外,Invoke-Command可以很好地為您處理多執行緒,因為-ComputerName接受了一個string[](array帶主機的)。
Invoke-Command [[-ComputerName] <String[]>]
Get-WinEvent [-ComputerName <String>]
這是您可以的基本示例,首先在作業的范圍內加載函式,然后呼叫它。請注意,這是并行運行 11 個作業。如果您正在尋找更“高效的多執行緒”,因為Start-Job它可以說比普通的線性回圈慢,請考慮使用TheadJob模塊或使用Runspace.
function sayhello ([string]$Name, [int]$Job) {
"Hello $Name from Job $Job..."
Start-Sleep 10
}
$funcDef = "function sayhello {$function:sayhello}"
# Each Job should take 10 seconds
$elapsed = [System.Diagnostics.Stopwatch]::StartNew()
0..10 | ForEach-Object {
Start-Job -ScriptBlock {
param($def, $name, $job)
. ([scriptblock]::Create($def)) # => Load the function in this scope
sayhello -Name $name -Job $job
} -ArgumentList $funcDef, 'world', $_
} | Receive-Job -AutoRemoveJob -Wait
$elapsed.Stop()
"`nElapsed Time: {0} seconds" -f
$elapsed.Elapsed.TotalSeconds.ToString('0.##')
結果:
Hello world from Job 1...
Hello world from Job 6...
Hello world from Job 0...
Hello world from Job 4...
Hello world from Job 3...
Hello world from Job 5...
Hello world from Job 2...
Hello world from Job 10...
Hello world from Job 7...
Hello world from Job 9...
Hello world from Job 8...
Elapsed Time: 13.82 seconds
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/381812.html
標籤:电源外壳
上一篇:如何在txt檔案中回傳方法的內容
