限制并发PowerShell作业的数量

时间:2014-02-27 13:33:44

标签: powershell concurrency numbers limit jobs

我知道之前已经问过这个问题,我已经看过几个可能的解决方案,但我似乎无法使其中的任何一个适用于我的脚本。我的脚本不是一个成品,需要一些清理,但它肯定是有效的。

该脚本的基本功能是创建虚拟机的快照,然后克隆它们以进行备份。一切都按预期工作,但问题是它让我的vcenter跪了下来,因为它同时淹没了太多的工作。我想要同时限制一次运行的工作量到3-4。任何人都可以帮我一把吗?在此先感谢...这是我的代码:

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

我尝试在脚本末尾抛出以下代码,但没有运气:

$backupinfo | % {Start-Job -Scriptblock $scriptblock -ArgumentList $_ | Out-Null}

While((Get-Job -State 'Running').Count -ge 3)
    {
        Start-Sleep -Milliseconds 10
    }

更新**

我尝试使用此处提供的答案Run N parallel jobs in powershell

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
}

当我运行我的脚本时,它所做的就是为每个虚拟机返回这个,并且从不执​​行任何任务(快照等)

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         : {}

您可以提供哪些指导?

1 个答案:

答案 0 :(得分:1)

考虑使用工作流程。它有一个并行的foreach,它应该智能地限制并发执行的数量,例如:

workflow New-Clone([string[]]$Customer) {
    InlineScript { Import-Module modules }
    foreach -parallel($cust in $Customer) {
        InlineScript {
            ...
            $vm = Get-VM $using:cust.MasterVM
            ...
        } 
    }
}

这需要PowerShell V3或更高版本才能获得工作流支持。