Multithreading Powershell运行空间赢得';不执行

Multithreading Powershell运行空间赢得';不执行,multithreading,powershell,Multithreading,Powershell,我对我想写的剧本有点不知所措 简言之:我想扫描我的域计算机的WinRM连接-我可以做得很好。问题是,完成这个任务需要5分钟——这就是为什么我想多线程处理这个任务 正在工作的非多线程代码: 这基本上只是我的skcript所做/将要做的一小部分,但这部分需要花费很多时间 我的运行空间测试失败——我基本上没有得到任何结果。文本框中没有任何内容,命令行中没有输出,我基本上不知道自己做错了什么 多线程代码: 运行空间代码来自以下指南的混合: 我希望有人能帮助我,告诉我失败的地方/原因。谢谢 好吧,谢谢

我对我想写的剧本有点不知所措

简言之:我想扫描我的域计算机的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)
    }
   }
  }
}