Powershell multiple threading headache

Soldato
Joined
8 Mar 2005
Posts
3,676
Location
London, UK
I have almost got the following code to work as expected;

Code:
Param($ScriptFile = 'C:\local_apps\ctx_xd_check\ps_get-ll.ps1',
    $ComputerList = 'C:\local_apps\ctx_xd_check\machines2.txt',
    $MaxThreads = 50,
    $SleepTimer = 8000,
    $MaxWaitAtEnd = 600,
    $OutputType = "Gridview")
    
$Computers = Get-Content $ComputerList
 
 
"Killing existing jobs . . ."
Get-Job | Remove-Job -Force
"Done."
 
$i = 0
 
ForEach ($Computer in $Computers){
    While ($(Get-Job -state running).count -ge $MaxThreads){
        Write-Progress  -Activity "Creating Server List" -Status "Waiting for threads to close" -CurrentOperation "$i threads created - $($(Get-Job -state running).count) threads open" -PercentComplete ($i / $Computers.count * 100) Start-Sleep -Milliseconds $SleepTimer
    }
 
"Starting job - $Computer"
    $i++
    Start-Job -FilePath $ScriptFile -ArgumentList $Computer -Name $Computer | Out-Null
    Write-Progress  -Activity "Creating Server List" -Status "Starting Threads" -CurrentOperation "$i threads created - $($(Get-Job -state running).count) threads open" -PercentComplete ($i / $Computers.count * 100)
    
}
 
$Complete = Get-date
 
While ($(Get-Job -State Running).count -gt 0){
    $ComputersStillRunning = ""
    ForEach ($System  in $(Get-Job -state running)){$ComputersStillRunning += ", $($System.name)"}
    $ComputersStillRunning = $ComputersStillRunning.Substring(2)
    Write-Progress  -Activity "Creating Server List" -Status "$($(Get-Job -State Running).count) threads remaining" -CurrentOperation "$ComputersStillRunning" -PercentComplete ($(Get-Job -State Completed).count / $(Get-Job).count * 100)
    If ($(New-TimeSpan $Complete $(Get-Date)).totalseconds -ge $MaxWaitAtEnd){"Killing all jobs still running . . .";Get-Job -State Running | Remove-Job -Force}
    Start-Sleep -Milliseconds $SleepTimer
}
 
"Reading all jobs"
 
If ($OutputType -eq "Text"){
    ForEach($Job in Get-Job){
        "$($Job.Name)"
        "****************************************"
        Receive-Job $Job #| Select-Object * -ExcludeProperty RunspaceId #| Export-CSV 'N:\scripts\powershell\test3.csv'  -NoTypeInformation
        " "
    }
}
ElseIf($OutputType -eq "Gridview"){
#    Get-Job | Receive-Job | Select-Object * -ExcludeProperty RunspaceId | Export-CSV 'N:\scripts\powershell\test.csv'  -NoTypeInformation
#    Get-Job | Receive-Job | Select-Object * -ExcludeProperty RunspaceId | Export-CSV '\\ukz527\vc$\vbs\scripts\powershell\PS-Multi\PSmulti-Output.csv'  -NoTypeInformation
    Get-Job | Receive-Job | Select-Object * -ExcludeProperty RunspaceId | ConvertTo-Csv -NoTypeInformation | % {$_.Replace('"','')} | Out-File 'C:\local_apps\ctx_xd_check\LL-Output.csv' 
}

This pulls a server list and then executes a secondary script again each server. However as soon as it hits the thread limit (50 in this case), instead of the expected sleep/check logic kicking it throws out the following error message;

Code:
Write-Progress : Cannot bind parameter 'Id'. Cannot convert value "Start-Sleep"
 to type "System.Int32". Error: "Input string was not in a correct format."
At C:\local_apps\ctx_xd_check\psmulti.ps1:19 char:23
+         Write-Progress <<<<   -Activity "Creating Server List" -Status "Waiti
ng for threads to close" -CurrentOperation "$i threads created - $($(Get-Job -s
tate running).count) threads open" -PercentComplete ($i / $Computers.count * 10
0) Start-Sleep -Milliseconds $SleepTimer
    + CategoryInfo          : InvalidArgument: (:) [Write-Progress], Parameter
   BindingException
    + FullyQualifiedErrorId : CannotConvertArgumentNoMessage,Microsoft.PowerSh
   ell.Commands.WriteProgressCommand

Until the thread count drops below 50, at which point it restarts threads until it again hits 50 and throws out the same errors etc until it completes. the export works fine, albeit with considerably less rows of data than expected.

Would appreciate any pointers.

Cheers, Paul.
 
Soldato
OP
Joined
8 Mar 2005
Posts
3,676
Location
London, UK
So at this point;
Code:
 While ($(Get-Job -state running).count -ge $MaxThreads){
        Write-Progress  -Activity "Creating Server List" -Status "Waiting for threads to close" -CurrentOperation "$i threads created - $($(Get-Job -state running).count) threads open" -PercentComplete ($i / $Computers.count * 100) Start-Sleep -Milliseconds $SleepTimer
    }

Not sure I fully understand. This should loop until it drops below MaxThreads at which point it starts additional threads.

Hmm.
 
Back
Top Bottom