title: Limit number of concurrent powershell jobs
body: <p>I know this question has been asked before and i have seen a couple of possible solutions, but i can't seem to be able to make any of them work for my script.  My script is not a finished product, needs some cleaning up, but it definitely works at the moment.  </p>
  
  <p>The basic function of the script is that it creates snapshots of virtual machines, and then clones them for backup purposes.  Everything works as expected, but the problem is it brings my vcenter to it's knees because it is flooding it with too many jobs at once.  I was wanting to limit the amount of jobs that run at once to maybe 3-4 at the same time.  Can anyone give me a hand?  Thanks in advance... Here is my code:</p>
  
  <pre><code>Add-PSSnapin VMware.VimAutomation.Core
  
  #Connect to vCenter
  Connect-VIServer vcenter.mydomain.com
  
  #Define variables
  $vmhost = get-vmhost -name 10.1.1.10
  
  #Export list of VM's
  get-vmhost -name $vmhost | get-vm | select Name, BackupDS | Export-Csv -NoTypeInformation test.csv
  
  #Edit CSV to populate BackupDS Column
  (Import-Csv test.csv) | % { $_.BackupDS = '[NAS1]' +$_.BackupDS; $_ } | Export-Csv test.csv -NoTypeInformation
  
  #Edit CSV file to format required by script
  (gc test.csv) | foreach-object{$_ -replace 'Name','MasterVM'} | set-content test.csv -force
  
  #Import Backup CSV
  $backupinfo =  Import-Csv test.csv
  
  
  
  $scriptblock = {
  Param($customer)
  
      Add-PSSnapin VMware.VimAutomation.Core
  
      #Connect to vCenter
      Connect-VIServer vcenter.mydomain.com
  
      #Define variables
      $vmhost = get-vmhost -name 10.1.1.10
  
      #Set Date format for clone names
      $date = Get-Date -Format "MMddyyyy"
  
      #Set Date format for emails
      $time = (Get-Date -f "HH:MM")
  
      $vm = Get-VM $customer.MasterVM
  
      #Send Start Email
      #C:\scripts\backupstartedemail.ps1
  
      # Create new snapshot for clone
      $cloneSnap = $vm | New-Snapshot -Name "Clone Snapshot"
  
      # Get managed object view
      $vmView = $vm | Get-View
  
      # Get folder managed object reference
      $cloneFolder = $vmView.parent
  
      # Build clone specification
      $cloneSpec = new-object Vmware.Vim.VirtualMachineCloneSpec
      $cloneSpec.Snapshot = $vmView.Snapshot.CurrentSnapshot
  
      # Make linked disk specification
      $cloneSpec.Location = new-object Vmware.Vim.VirtualMachineRelocateSpec
      $cloneSpec.Location.Datastore = (Get-Datastore -Name $customer.BackupDS | Get-    View).MoRef
      $cloneSpec.Location.Transform =      [Vmware.Vim.VirtualMachineRelocateTransformation]::sparse
  
      $cloneName = "$vm-$date"
  
      # Create clone
      $vmView.CloneVM( $cloneFolder, $cloneName, $cloneSpec )
  
      # Write newly created VM to stdout as confirmation
      Get-VM $cloneName
  
      # Remove Snapshot created for clone
      Get-Snapshot -VM (Get-VM -Name $customer.MasterVM) -Name $cloneSnap | Remove-    Snapshot -confirm:$False
  
      # Remove clones machine from inventory
      remove-vm -vm $cloneName -confirm:$false
  
      #Send Complete Email
      #C:\scripts\backupcompletedemail.ps1
  }
  
  $backupinfo | % {Start-Job -Scriptblock $scriptblock -ArgumentList $_ | Out-Null}
  
  Get-Job | Wait-Job | Receive-Job
  </code></pre>
  
  <p>I've tried throwing the following code at the end of the script with no luck:</p>
  
  <pre><code>$backupinfo | % {Start-Job -Scriptblock $scriptblock -ArgumentList $_ | Out-Null}
  
  While((Get-Job -State 'Running').Count -ge 3)
      {
          Start-Sleep -Milliseconds 10
      }
  </code></pre>
  
  <hr>
  
  <p>Update**</p>
  
  <p>I tried using the answer provided here, <a href="https://stackoverflow.com/questions/8781666/run-n-parallel-jobs-in-powershell">Run N parallel jobs in powershell</a>.  </p>
  
  <pre><code>Add-PSSnapin VMware.VimAutomation.Core
  
  #Connect to vCenter
  Connect-VIServer vcenter.mydomain.com
  
  #Define variables
  $vmhost = get-vmhost -name 10.1.1.10
  
  #Export list of VM's
  get-vmhost -name $vmhost | get-vm | select Name, BackupDS | Export-Csv -NoTypeInformation     test.csv
  
  #Edit CSV to populate BackupDS Column
  (Import-Csv test.csv) | % { $_.BackupDS = '[NAS1]' +$_.BackupDS; $_ } | Export-Csv test.csv     -NoTypeInformation
  
  #Edit CSV file to format required by script
  (gc test.csv) | foreach-object{$_ -replace 'Name','MasterVM'} | set-content test.csv -force
  
  #Import Backup CSV
  $backupinfo =  Import-Csv test.csv
  
  #Set Date format for clone names
  $date = Get-Date -Format "MMddyyyy"
  
  #Set Date format for emails
  $time = (Get-Date -f "HH:MM")
  
  foreach ($customer in $backupinfo) {
      $running = @(Get-Job | Where-Object { $_.State -eq 'Running' })
      if ($running.Count -le 8) {
          Start-Job {
               $vm = Get-VM $customer.MasterVM
  
      #Send Start Email
      #C:\scripts\backupstartedemail.ps1
  
      # Create new snapshot for clone
      $cloneSnap = $vm | New-Snapshot -Name "Clone Snapshot"
  
      # Get managed object view
      $vmView = $vm | Get-View
  
      # Get folder managed object reference
      $cloneFolder = $vmView.parent
  
      # Build clone specification
      $cloneSpec = new-object Vmware.Vim.VirtualMachineCloneSpec
      $cloneSpec.Snapshot = $vmView.Snapshot.CurrentSnapshot
  
      # Make linked disk specification
      $cloneSpec.Location = new-object Vmware.Vim.VirtualMachineRelocateSpec
      $cloneSpec.Location.Datastore = (Get-Datastore -Name $customer.BackupDS | Get-    View).MoRef
      $cloneSpec.Location.Transform =      [Vmware.Vim.VirtualMachineRelocateTransformation]::sparse
  
      $cloneName = "$vm-$date"
  
      # Create clone
      #$vmView.CloneVM( $cloneFolder, $cloneName, $cloneSpec )
  
      # Write newly created VM to stdout as confirmation
      #Get-VM $cloneName
  
      # Remove Snapshot created for clone
      Get-Snapshot -VM (Get-VM -Name $customer.MasterVM) -Name $cloneSnap | Remove-Snapshot -     confirm:$False
  
      # Remove clones machine from inventory
      #remove-vm -vm $cloneName -confirm:$false
  
      #Send Complete Email
      #C:\scripts\backupcompletedemail.ps1
          }
      } else {
           $running | Wait-Job
      }
      Get-Job | Receive-Job
  }
  </code></pre>
  
  <p>When i run my script all it does is return this for each virtual machine, and never does any of the tasks (snapshots, etc.)</p>
  
  <pre><code>HasMoreData   : True
  StatusMessage :
  Location      : localhost
  Command       :
                       $vm = Get-VM $customer.MasterVM
                       ..................
                       rest of my code
                       ..................
  JobStateInfo  : Running
  Finished      : System.Threading.ManualResetEvent
  InstanceId    : 81ac8e67-0267-4d11-998b-0e8cfa95292b
  Id            : 40
  Name          : Job40
  ChildJobs     : {Job41}
  PSBeginTime   : 2/27/2014 12:41:19 PM
  PSEndTime     :
  PSJobTypeName : BackgroundJob
  Output        : {}
  Error         : {}
  Progress      : {}
  Verbose       : {}
  Debug         : {}
  </code></pre>
  
  <p>Any guidance you can provide?</p>