Multithreading Powershell运行空间赢得';不执行
我对我想写的剧本有点不知所措 简言之:我想扫描我的域计算机的WinRM连接-我可以做得很好。问题是,完成这个任务需要5分钟——这就是为什么我想多线程处理这个任务 正在工作的非多线程代码: 这基本上只是我的skcript所做/将要做的一小部分,但这部分需要花费很多时间 我的运行空间测试失败——我基本上没有得到任何结果。文本框中没有任何内容,命令行中没有输出,我基本上不知道自己做错了什么 多线程代码: 运行空间代码来自以下指南的混合:Multithreading Powershell运行空间赢得';不执行,multithreading,powershell,Multithreading,Powershell,我对我想写的剧本有点不知所措 简言之:我想扫描我的域计算机的WinRM连接-我可以做得很好。问题是,完成这个任务需要5分钟——这就是为什么我想多线程处理这个任务 正在工作的非多线程代码: 这基本上只是我的skcript所做/将要做的一小部分,但这部分需要花费很多时间 我的运行空间测试失败——我基本上没有得到任何结果。文本框中没有任何内容,命令行中没有输出,我基本上不知道自己做错了什么 多线程代码: 运行空间代码来自以下指南的混合: 我希望有人能帮助我,告诉我失败的地方/原因。谢谢 好吧,谢谢
我希望有人能帮助我,告诉我失败的地方/原因。谢谢 好吧,谢谢你的提示,但问题要简单得多 我试图在错误的位置获取数据。此外,我还简化了我的脚本。我不再在函数中调用函数了 注1:我没有意识到我可以/需要在运行空间的scriptblock中使用返回值 注2:我现在正在收集数据,并将其插入while循环中的函数末尾的列表框(或我想插入的任何其他位置),在那里我基本上构建了我的运行空间 注3:我提到的所有“GUI部件”都位于不同的文件中,并且确实存在 我把持续时间缩短到大约20秒(之前差不多5分钟) 我使用的线程数量有点随机,这是工作最快的组合之一 代码:
$objListboxLeft
、$objListboxCenter
和$objListboxRight
在运行空间中不存在,这可能就是它失败的原因。从ScriptBlock中返回一个对象,我认为您可以通过使用来简化脚本。类似于invoke命令-computername$computers-scriptblock{#check winrm localy}-asjob
@Kayasax仍然无法解决他试图修改执行范围/运行空间中不存在的对象的问题/process@MathiasR.Jessen你说得对,我指的是最初的“糟糕表现”问题。谢谢大家的意见。很抱歉,缺少我构建的详细信息-列表框确实存在。我只发布了一个我正在调用的函数。此外,我以前也使用过作业——这些作业需要5分钟的时间(也许我实施得很糟糕)——我自己也对我的问题给出了答案。享受吧!
# this is normaly a textfile with lots of machine hostnames
$computers = "PC100","PC106","PC124","PC115","PC21"
function checkMachine($computers){
$ErrorActionPreference = "Stop"
foreach ($item in $computers){
#the function contest only performs a ping and returne $true or $false
$connection = ConTest($item)
if($connection){
try{
$winRM = test-wsman -ComputerName $item
if($winRM){
write-host "winRM"
[void] $objListboxLeft.Items.Add($item)
}
}catch{
write-host "NO winRM"
[void] $objListboxCenter.Items.Add($item)
}
}else{
write-host "offline"
[void] $objListboxRight.Items.Add($item)
}
}
}
function MulticheckMachine($computers){
$ErrorActionPreference = "Stop"
$runspaceCollection = @()
$runspacePool = [RunspaceFactory]::CreateRunspacePool(1,5)
$runspacePool.open()
$scriptBlock = {
Param($item)
$connection = ConTest($item)
if($connection){
try{
test-wsman -ComputerName $item
$winRM = test-wsman -ComputerName $item
if($winRM){
write-host "winRM"
[void] $objListboxLeft.Items.Add($item)
}
}catch{
write-host "NO winRM"
[void] $objListboxCenter.Items.Add($item)
}
}else{
write-host "offline"
[void] $objListboxRight.Items.Add($item)
}
}
Foreach($item in $computers){
$powershell = [PowerShell]::Create().AddScript($scriptBlock).AddArgument($item)
$powershell.runspacePool = $runspacePool
[Collections.Arraylist]$runspaceCollection += New-Object -TypeName PSObject -Property @{
Runspace = $powershell.BeginInvoke()
PowerShell = $powershell
}
$runspaceCollection
}
While($runspaceCollection){
Foreach($runspace in $runspaceCollection.ToArray()){
If($runspace.Runspace.IsCompleted){
$runspace.PowerShell.EndInvoke($runspace.Runspace)
$runspace.PowerShell.Dispose()
$runspaceCollection.Remove($runspace)
}
}
}
}
function multiCheckMachine($computers){
$ErrorActionPreference = "Stop"
$runspaceCollection = @()
$runspacePool = [RunspaceFactory]::CreateRunspacePool(1,50)
$runspacePool.open()
$scriptBlock = {
Param($item)
$FQDNitem = "$item.domain.com"
$address = nslookup $FQDNitem
if($address -like "addresses*"){
$address = $address[5] -replace ".* ",""
}else{
$address = $address[4] -replace ".* ",""
}
$con = ping -n 1 $address
if($con[2] -like "*Bytes*"){
$winRM = test-wsman -ComputerName $item
if($winRM){
return "$item.winRM"
}else{
return "$item.NOremote"
}
}else{
return "$item.offline"
}
}
Foreach($item in $computers){
$powershell = [PowerShell]::Create().AddScript($scriptBlock).AddArgument($item)
$powershell.runspacePool = $runspacePool
[Collections.Arraylist]$runspaceCollection += New-Object -TypeName PSObject -Property @{
Runspace = $powershell.BeginInvoke()
PowerShell = $powershell
}
}
While($runspaceCollection){
Foreach($runspace in $runspaceCollection.ToArray()){
If($runspace.Runspace.IsCompleted){
if($runspace.PowerShell.EndInvoke($runspace.Runspace) -like "*winrm"){
[void] $objListboxOnline.Items.Add($runspace.PowerShell.EndInvoke($runspace.Runspace).split(".")[0])
}elseif($runspace.PowerShell.EndInvoke($runspace.Runspace) -like "*NOremote"){
[void] $objListboxNoWinRM.Items.Add($runspace.PowerShell.EndInvoke($runspace.Runspace).split(".")[0])
}elseif($runspace.PowerShell.EndInvoke($runspace.Runspace) -like "*offline"){
[void] $objListboxOffline.Items.Add($runspace.PowerShell.EndInvoke($runspace.Runspace).split(".")[0])
}
$runspace.PowerShell.Dispose()
$runspaceCollection.Remove($runspace)
}
}
}
}