2016-04-06 56 views
0

我已经在PowwerShell中用Get-JobWait-Job做了很多关于多线程的阅读,但是仍然无法解决这个问题。使用PowerShell的多线程

最后,我将把它作为一个基于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

我会避免Start-Job线程 - 为了效率尝试一个runspace工厂。

这是一个基本的设置,可能是有用的(我也有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) 
} 
+0

嘿,谢谢,我在'scriptblock'中复制我的脚本,但没有任何事情发生?数据假设在哪里显示? –

+0

尝试'Write-Output'而不是'Write-Host' – xXhRQ8sD2L7Z

+0

好吧,我可以得到它来输出我的结果,只需要解决它就可以添加到gui中,谢谢我马上添加并粘贴我的结果:) –