Good afternoon,
I’m currently banging my head against the desk trying to figure this out. I’m completely comfortable with runspaces… I use them all the time to throttle large amounts of data copies, etc… since you can set up a Runspace pool of 1-5 active tasks… even though you added 50 tasks to the list, only 5 at a time will run. And that’s great, i love it. Works quite well.
My problem is… I’m trying something new. I want to be able to query WHICH of the 50 tasks is actually running. So lets say i’ve got some computers I want to run commands against. I limit the number of active tasks to 3 but i’ve got 5 computers. As one of the first 3 finishes, #4 would start, etc… When I start my runspaces and add them to the pool, one of the properties I add is called ‘Computer’ and I can clearly see that when I view the $RunspaceCollection The problem i have here is that there’s no property for ‘active’ or ‘running’. The only thing I can find that is accurate is a property on each runspace item within the RunspaceCollection. I.E.:
$RunspaceColletion.runspace[0] will give me the details about the first task added to the pool. There is an ‘IsCompleted’ value of False or True. They all start out as false… and as each task finishes, they get marked IsCompleted = $True automatically. But I can’t tell which ones are actually running and it’s driving me nuts. I want to be able to update my screen saying COMPUTER1, COMPUTER2, and COMPUTER3 are currently copying… and update a status elsewhere in my code.
Confused yet?
Example code that runs 5 computers through a 60 second sleep just for an example, so you have 60 seconds to look things over. If you run all of the code prior to the WHILE statement towards the bottom, you can look at the values of the different objects/variables.
$Computers = "COMPUTER1","COMPUTER2","COMPUTER3","COMPUTER4","COMPUTER5" #Create empty Array $RunspaceCollection = @() #Open Define the number of processes the pool should allow. minimum and maximum values (1 and 5) $RunspacePool = [RunspaceFactory]::CreateRunspacePool(1,3) $RunspacePool.Open() #Define the actual work each runspace will perform. $ScriptBlock = { Param($Computer) #Get-Process -ComputerName $Computer -FilterHashtable @{Logname='System';Id=1074} -MaxEvents 150 sleep 60 } Foreach($Computer in $Computers){ #Create a PowerShell object to run add the script and argument. $Powershell = [PowerShell]::Create().AddScript($ScriptBlock).AddArgument($Computer) #Specify runspace to use $Powershell.RunspacePool = $RunspacePool #Create Runspace collection [Collections.Arraylist]$RunspaceCollection += New-Object -TypeName PSObject -Property @{ Runspace = $PowerShell.BeginInvoke() PowerShell = $PowerShell Computer = $Computer } } #Check the RunSpace and validate that all of the tasks in the pool have completed. Once completed, send 'EndInvoke' to each one. # Once all of the tasks are completed, remove the runspace. While($RunspaceCollection){ Foreach($Runspace in $RunspaceCollection.ToArray()){ If($Runspace.Runspace.IsCompleted){ $Runspace.PowerShell.EndInvoke($Runspace.Runspace) $Runspace.PowerShell.Dispose() $RunspaceCollection.Remove($Runspace) } } }