SCVMM 2012 SP1批量创建VM时并发作业数限制问题求助
控制SCVMM 2012 SP1中New-SCVirtualMachine的并发作业数量
我之前帮不少人解决过SCVMM批量创建VM的并发问题,你遇到的情况很典型——虽然SCVMM本身没硬性限制并发作业数,但PowerShell的会话资源限制会导致一次性提交太多作业失败。下面给你两种简便且实用的控制并发的方法,你可以根据自己的场景选择:
方法1:用Start-Job配合ThrottleLimit(简单易上手)
这种方法利用PowerShell的Start-Job自带的并发限制参数,不需要复杂的代码,适合快速实现100台左右的VM批量创建。
步骤示例:
- 先定义好所有要创建的VM配置参数(比如名称、模板、主机组等),把它们放到一个数组里。
- 设置合适的并发数(建议从10开始测试,根据服务器性能调整),通过
-ThrottleLimit控制同时运行的作业数。
# 加载SCVMM模块(如果没自动加载的话) Import-Module VirtualMachineManager # 定义100台VM的配置列表,这里只是示例,替换成你实际的参数 $vmConfigs = 1..100 | ForEach-Object { @{ VMName = "Production-VM-$_" TemplateName = "WindowsServer2012-Template" # 你的模板名称 HostGroupName = "Datacenter-HostGroup" # 你的主机组名称 # 可以添加其他参数,比如CPU、内存、存储路径等 } } # 设置并发作业数,先从10开始,后续根据运行情况调整 $maxConcurrentJobs = 10 # 批量提交作业并控制并发 $runningJobs = $vmConfigs | ForEach-Object { $config = $_ Start-Job -ScriptBlock { param($vmConfig) # 在作业会话中重新获取SCVMM对象(避免跨会话序列化问题) $template = Get-SCVMTemplate -Name $vmConfig.TemplateName $hostGroup = Get-SCVMHostGroup -Name $vmConfig.HostGroupName try { $newVM = New-SCVirtualMachine -Name $vmConfig.VMName ` -VMTemplate $template ` -VMHostGroup $hostGroup return @{Status="Success"; VMName=$newVM.Name} } catch { return @{Status="Failed"; VMName=$vmConfig.VMName; Error=$_.Exception.Message} } } -ArgumentList $config -ThrottleLimit $maxConcurrentJobs } # 等待所有作业完成,然后获取结果 Wait-Job $runningJobs $results = Receive-Job $runningJobs # 统计成功/失败情况 $successCount = ($results | Where-Object {$_.Status -eq "Success"}).Count $failedCount = ($results | Where-Object {$_.Status -eq "Failed"}).Count Write-Host "批量创建完成:成功$successCount台,失败$failedCount台"
方法2:用Runspace池(更高效,适合大规模创建)
如果需要创建更多VM(比如几百台),Runspace池的性能比Start-Job更好,因为它的开销更小,并发控制更精准。
步骤示例:
Import-Module VirtualMachineManager $vmConfigs = 1..100 | ForEach-Object { @{ VMName = "Production-VM-$_" TemplateName = "WindowsServer2012-Template" HostGroupName = "Datacenter-HostGroup" } } # 设置最大并发数 $maxConcurrent = 12 # 创建Runspace池,指定最小和最大并发数 $runspacePool = [RunspaceFactory]::CreateRunspacePool(1, $maxConcurrent) $runspacePool.Open() $jobList = @() # 遍历配置,提交到Runspace池 foreach ($config in $vmConfigs) { # 创建PowerShell实例 $psInstance = [PowerShell]::Create().AddScript({ param($vmName, $templateName, $hostGroupName) try { $template = Get-SCVMTemplate -Name $templateName $hostGroup = Get-SCVMHostGroup -Name $hostGroupName $newVM = New-SCVirtualMachine -Name $vmName -VMTemplate $template -VMHostGroup $hostGroup return @{Status="Success"; VMName=$newVM.Name} } catch { return @{Status="Failed"; VMName=$vmName; Error=$_.Exception.Message} } }).AddArgument($config.VMName).AddArgument($config.TemplateName).AddArgument($config.HostGroupName) # 关联到Runspace池 $psInstance.RunspacePool = $runspacePool # 开始异步执行 $jobList += [PSCustomObject]@{ PowerShell = $psInstance AsyncResult = $psInstance.BeginInvoke() } } # 等待所有作业完成并获取结果 $results = @() foreach ($job in $jobList) { $result = $job.PowerShell.EndInvoke($job.AsyncResult) $results += $result # 释放资源 $job.PowerShell.Dispose() } # 关闭Runspace池 $runspacePool.Close() $runspacePool.Dispose() # 统计结果 $successCount = ($results | Where-Object {$_.Status -eq "Success"}).Count $failedCount = ($results | Where-Object {$_.Status -eq "Failed"}).Count Write-Host "批量创建完成:成功$successCount台,失败$failedCount台"
关键注意事项
- 并发数调整:不要一开始就设太高,建议从10-15开始测试,根据SCVMM服务器的CPU、内存、存储IO以及网络带宽逐步调整,避免给基础设施带来过大压力。
- 对象传递:跨PowerShell会话传递SCVMM对象容易出现序列化问题,所以建议传递对象名称,然后在作业脚本块中重新获取对象(比如上面示例中的
Get-SCVMTemplate和Get-SCVMHostGroup)。 - 错误处理:添加
try-catch逻辑可以捕获创建过程中的异常,方便后续排查问题。 - SCVMM监控:可以在SCVMM控制台的「作业」视图中实时监控这些VM创建作业的状态,及时发现异常。
内容的提问来源于stack exchange,提问作者Uh Trog
相关产品推荐
相关产品推荐

