我已经使用Get-Job
和Wait-Job
在PowwerShell中完成了大量关于多线程的阅读,但似乎仍无法解决这个问题。
最终,我会将此作为基于GUI的脚本运行,并且不希望我的GUI在执行任务时冻结。
脚本正在查找我的域控制器的事件日志,然后获取我想要的详细信息,然后输出它们,它就像我需要它一样。
我可以使用Invoke-Command {#script goes here} -ComputerName ($_) -AsJob -JobName $_
开始工作并运行作业。
下面的脚本:
Clear-Host
Get-Job | Remove-Job
(Get-ADDomainController -Filter *).Name | ForEach-Object {
Invoke-Command -ScriptBlock {
$StartTime = (Get-Date).AddDays(-4)
Try{
Get-WinEvent -FilterHashtable @{logname='Security'; id=4740;StartTime=$StartTime} -ErrorAction Stop `
| Select-Object * | ForEach-Object {
$Username = $_.Properties[0].Value
$lockedFrom = $_.Properties[1].Value
$DC = $_.Properties[4].Value
$Time = $_.TimeCreated
Write-Host "---------------------------------------------"
Write-Host $Username
Write-Host $lockedFrom
Write-Host $DC
Write-Host $Time
Write-Host "---------------------------------------------"
}#ForEach-Object
}catch [Exception] {
If ($_.Exception -match "No events were found that match the specified selection criteria") {
Write-Host "No events for locked out accounts." -BackgroundColor Red
}#If
}#Try Catch
} -ComputerName ($_) -AsJob -JobName $_ | Out-Null # Invoke-Command
}#ForEach-Object
目前我有一个While
循环告诉我它等待然后向我显示结果:
(Get-ADDomainController -Filter *).Name | ForEach-Object {
Write-Host "Waiting for: $_."
While ($(Get-Job -Name $_).State -ne 'Completed') {
#no doing anything here
}#While
Receive-Job -Name $_ -Keep
}#ForEach-Object
#clean up the jobs
Get-Job | Remove-Job
考虑到我的GUI(要创建),我将为每个域控制器创建一个列并在每个标题下显示结果,如何使它不冻结我的GUI并在它们到达时显示结果?
我知道有几次被问过,但是我不能解决这些例子。
答案 0 :(得分:0)
我会避免使用Start-Job
进行线程处理 - 为了提高效率,请尝试运行空间工厂。
这是一个基本设置,可能很有用(我也有PS 4.0),并且可以接受建议/改进。
$MaxThreads = 2
$ScriptBlock = {
Param ($ComputerName)
Write-Output $ComputerName
#your processing here...
}
$runspacePool = [RunspaceFactory]::CreateRunspacePool(1, $MaxThreads)
$runspacePool.Open()
$jobs = @()
#queue up jobs:
$computers = (Get-ADDomainController -Filter *).Name
$computers | % {
$job = [Powershell]::Create().AddScript($ScriptBlock).AddParameter("ComputerName",$_)
$job.RunspacePool = $runspacePool
$jobs += New-Object PSObject -Property @{
Computer = $_
Pipe = $job
Result = $job.BeginInvoke()
}
}
# wait for jobs to finish:
While ((Get-Job -State Running).Count -gt 0) {
Get-Job | Wait-Job -Any | Out-Null
}
# get output of jobs
$jobs | % {
$_.Pipe.EndInvoke($_.Result)
}