Hi
I’m trying to mass generate *.mof Files for servers.
I made a script, which generates one Dsc configuration per server out of json file.
After the config is created, i try to mass execute these configurations.
If i run them sequentially, it takes around 30 seconds for 20 servers. If i try to use a RunspacePool for a parallel execution with 10 threads it takes up to a minute for the same amount of servers. Can anyone explain, why it’s slower with Runspaces?
#This is a modified version of the version from https://gist.github.com/proxb/803fee30f0df244fd850 # Create an array of computers to do work against $Scripts = Get-ChildItem -Path C:\Dsc_Configurations # Create an empty array that we'll use later $RunspaceCollection = @() # This is the array we want to ultimately add our information to [Collections.Arraylist]$qwinstaResults = @() # Create a Runspace Pool with a minimum and maximum number of run spaces. (http://msdn.microsoft.com/en-us/library/windows/desktop/dd324626(v=vs.85).aspx) $RunspacePool = [RunspaceFactory]::CreateRunspacePool(1, 5) # Open the RunspacePool so we can use it $RunspacePool.Open() # Define a script block to actually do the work $ScriptBlock = { Param($Script) $queryResults = & C:\Dsc_Configurations\$Script $queryResults } # Create PowerShell objects, then for each one add the unique computer name. Foreach ($Script in $Scripts) { write-host $Script # Create a PowerShell object to run add the script and argument. # We first create a Powershell object to use, and simualtaneously add our script block we made earlier, and add our arguement that we created earlier $Powershell = [PowerShell]::Create().AddScript($ScriptBlock).AddArgument($Script) # Specify runspace to use # This is what let's us run concurrent and simualtaneous sessions $Powershell.RunspacePool = $RunspacePool # Create Runspace collection # When we create the collection, we also define that each Runspace should begin running [Collections.Arraylist]$RunspaceCollection += New-Object -TypeName PSObject -Property @{ Runspace = $PowerShell.BeginInvoke() PowerShell = $PowerShell } #/New-Object } #/ForEach # Now we need to wait for everything to finish running, and when it does go collect our results and cleanup our run spaces # We just say that so long as we have anything in our RunspacePool to keep doing work. This works since we clean up each runspace as it completes. While ($RunspaceCollection) { # Just a simple ForEach loop for each Runspace to get resolved Foreach ($Runspace in $RunspaceCollection.ToArray()) { # Here's where we actually check if the Runspace has completed If ($Runspace.Runspace.IsCompleted) { # Since it's completed, we get our results here [void]$qwinstaResults.Add($Runspace.PowerShell.EndInvoke($Runspace.Runspace)) # Here's where we cleanup our Runspace $Runspace.PowerShell.Dispose() $RunspaceCollection.Remove($Runspace) } #/If } #/ForEach } #/While