Create multiple vm in parallel using powershell runspace

I have a problem with creating multiple VM's from template in single VIServer. In following code when I choose if I put anything bigger than 1 in throttle script only executes one vm and don't create any other, it seems to have problem with keeping the session most likely just reset it or modify it in $global:DefaultVIServer.

Code below is based on question in this thread: Thread does not create multiple VMs (session issue) The answer is to keep the same session all the time but I couldn't get this to work

I wonder if anyone had working solution in using runspace in powershell to create multiple vms in vmware ?

Add-PSSnapin VMware.VimAutomation.Core | Out-Null
#import csv
= Import-CSV 'filename.csv' -UseCulture
#connections array
= @()
= 2
# Create session state
= [System.Management.Automation.Runspaces.InitialSessionState]::CreateDefault()
# Create runspace pool consisting of runspaces
= [RunspaceFactory]::CreateRunspacePool(1, $throttle, $sessionState, $host)
#array for jobs
= @()
#this contains all connected vSphere endpoints

= "domain\username"
= ConvertTo-SecureString -String "password" -AsPlainText -Force
= New-Object -TypeName "System.Management.Automation.PSCredential" -ArgumentList $User, $PWord 

# SctiptBlock to execute for each job
= {
Param ($VM, $ses)

Add-PSSnapin VMware.VimAutomation.Core | Out-Null
Write-Host $VM.Name "Father session: "  $ses.SessionSecret  

Connect-VIServer $VM.VIServer -Session $ses.SessionSecret -wa 0
Write-Host $VM.Name "Child session: "  $sessionf.SessionId

New-VM -Name $VM.Name -ResourcePool "..." -Location "Windows Servers" -Datastore "..." -DiskStorageFormat "..." -Notes "..." -Template "..."

# Starting script
Write-Host ("Starting script: {0}" -f (Get-Date))
= Get-Date

= 0
ForEach($VM in $VMs)

= $count + 1

Write-Host "Current connections:"

= Connect-VIServer $VM.VIServer -Credential $Credential -wa 0  

= [powershell]::create()
.RunspacePool = $RunspacePool
.AddScript($ScriptBlock).AddParameter("VM", $VM).AddParameter("ses", $ses)

Write-Host "Adding job to jobs list"  
+= New-Object PSObject -Property @{
RunNum = $count
Job = $Job
Result = $Job.BeginInvoke() | Out-Null

Write-Host "Waiting.." -NoNewline
Do {
Write-Host "." -NoNewline
Start-Sleep -Seconds 1
} While ( $Jobs.Result.IsCompleted -contains $false)

= Get-Date
= "{0:N4}" -f ($endTime-$startTime).TotalSeconds
Write-Host "All jobs finished in $totalSeconds seconds"

Tags (2)
3 Replies

I am certainly not an expert, but I just finished doing something like this but used a powershell workflow using the parallel command

Maybe this will help? Dunno

Workflow Engine








  foreach -parallel($name in $names)
     #Add the SnapIn and Connect to the Management vCenter
     Add-PSSnapin VMWare.VimAutomation.Core          
     Connect-VIServer -Server $Using:vc -Session $Using:ses -User $Using:vcuser -Password $Using:vcpass

        #do something


} #ForEach

} #Workflow


Engine -vcenter "" -session $global:DefaultVIServer.SessionSecret

Note: $names = "VM1","VM2","VM3"


Ran into the similar issue trying to run powershell inline script from RunDeck.

My script "rundeck-createvms.ps1" runs well in Windows interactive session but not from WinRM module used by RunDeck. So below is my wrapper for paraller vm creation.

$VCUser = "user"

$VCPass = "password"

$VCServer = "vcenter"

$vmNames = 'illya-test411','illya-test412','illya-test413' | Sort-Object

$myfolder = "IMAGETEST"

$mytemplate = "IMG-CENTOS704-VEN-201806092144"

$vmnetwork = ""

$vmmemorygb = 7

$vmmcpu = 3

Get-Module -ListAvailable VMWare* | Import-Module | Out-Null

Write-Host "PowerCLI is loaded" -ForegroundColor Green

Connect-VIServer -Server $VCServer -User $VCUser -Password $VCPass -WarningAction SilentlyContinue | Out-Null

Write-Host "Connected to vCenter as $VCUser" -ForegroundColor Green

workflow vmcreate













foreach -parallel($name in $names)




        Connect-VIServer -Server $Using:vcenter -Session $Using:session | Out-Null

        & C:\Scripts\rundeck-createvms.ps1 -vmname $Using:name -myfolder $Using:myfolder -mytemplate $Using:mytemplate `

        -vmnetwork $Using:vmnetwork -vmmemorygb $Using:vmmemorygb -vmmcpu $Using:vmmcpu




vmcreate `

-vcenter $global:DefaultVIServer.Name `

-session $global:DefaultVIServer.SessionSecret `

-names  $vmNames `

-myfolder $myfolder `

-mytemplate $mytemplate `

-vmnetwork $vmnetwork `

-vmmemorygb $vmmemorygb `

-vmmcpu $vmmcpu

0 Kudos

>if anyone had working solution in using runspace in powershell to create multiple vms in vmware ?

powershell runspace or jobs won't work in this case due to vmware session handling - spent quite some time troubleshooting.

You have a long script and in each job, you connect to vcenter,  "first" jobs finished and automatically disconnect which kills connection in other jobs that are still running. Therefore out of multiple background jobs, the one that finished first will be successful. The solution is to connect to vcenter once in control script and use workflow for parallel processing.

0 Kudos