title: Powershell v2.0 Using multiple threads
body: <p>Basic script idea:
  Hello. I've created a powershell script which I use to check the filesizes of certain executables, and then keep them in a text file. Next time the script runs, if a filesize differs it will replace the one in the text file with the new one. </p>
  
  <p>The structure:
  I have a main script and a folder which contains many scripts, each for every executable of which I want to check the filesize. So the scripts in the folder will return a string containing the link to the executable, which will be fed to the main script.</p>
  
  <p>The code:</p>
  
  <pre><code>$progdir = "C:\script\programms"
  $items = Get-ChildItem -filter *.ps1 -Path $progdir
  $webclient = New-Object System.Net.WebClient
  
  $filesizes = get-content C:\updatechecker\programms\filesizes
  if ($filesizes.length -ne $items.length) { 
      if ($filesizes.length -eq $null) {
          Write-Host ("Building filesize database...") -nonewline
      } 
      else { 
          Write-Host ("Rebuilding filesize database...") -nonewline 
      }
      clear-content  C:\programms\filesizes
  
      for ($i=0; $i -le $items.length-1; $i++) {
          $command = "c:\programms\" + $items[$i].name
          $link = &amp; $command
          $webclient.OpenRead($link) | Out-Null
          $filesize = $webclient.ResponseHeaders["Content-Length"]
          $filesize &gt;&gt; C:\programms\filesizes
      }
      echo "Done." 
  } 
  else {
      ...
  </code></pre>
  
  <p>Question:
  This for loop is the one I want to run in parallel. I need your advice on how to do this since I'm new to powershell. I tried to implement a few things I found but they didn't work correctly (took very long to finish, output errors, multiple entries of filesizes in my filesizes file). I suspect it's a synchronization issue and somehow I need to lock the critical parts. Isn't there anything like omp parallel for in powershell? :P</p>
  
  <p>Any help,advice on how to achieve this would be appreciated :)</p>
  
  <p>edit: </p>
  
  <pre><code>Get-Job | Remove-Job -Force
  $progdir = "C:\programms"
  $items = Get-ChildItem -filter *.ps1 -Path $progdir
  $webclient = New-Object System.Net.WebClient
  $filesizes = get-content C:\programms\filesizes
  
  $jobWork = {
      param ($MyInput)
      $command = "c:\programms\" + $MyInput
      $link = &amp; $command
      $webclient.OpenRead($link) | Out-Null
      $filesize = $webclient.ResponseHeaders["Content-Length"]
      $filesize &gt;&gt; C:\programms\filesizes
  
  }
  foreach ($item in $items) {
  
      Start-Job -ScriptBlock $jobWork -ArgumentList $item.name | out-null
  }
  
  Get-Job | Wait-Job
  Get-Job | Receive-Job | Out-GridView | out-null
  echo "Done."
  </code></pre>
  
  <p>Edit 2: Used code I found here: <a href="http://ryan.witschger.net/?p=22" rel="nofollow">http://ryan.witschger.net/?p=22</a></p>
  
  <pre><code>$mutex = new-object -TypeName System.Threading.Mutex -ArgumentList $false, “RandomGlobalMutexName”;
  $MaxThreads = 4
  $SleepTimer = 500
  
  
  $jobWork = {
      param ($MyInput)
      $webclient = New-Object System.Net.WebClient
      $command = "c:\programms\" + $MyInput
      $link = &amp; $command
      $webclient.OpenRead($link) | Out-Null
  
      $result = $mutex.WaitOne();
  
      $file = $webclient.ResponseHeaders["Content-Length"]
      $file &gt;&gt; C:\programms\filesizes
  
      $mutex.ReleaseMutex();
  }
  
  $progdir = "C:\programms"
  $items = Get-ChildItem -filter *.ps1 -Path $progdir
  $webclient = New-Object System.Net.WebClient
  $filesizes = get-content C:\programms\filesizes
  
  Get-Job | Remove-Job -Force
  
  $i = 0
  
  ForEach ($item in $items){
      While ($(Get-Job -state running).count -ge $MaxThreads){
  
          Start-Sleep -Milliseconds $SleepTimer
      }
  
      $i++
      Start-Job -ScriptBlock $jobWork -ArgumentList $item.name | Out-Null
  
  
  }
  </code></pre>