Quantcast
Channel: VMware Communities : All Content - All Communities
Viewing all articles
Browse latest Browse all 175326

Multithreading PowerCLI with RunspacePool

$
0
0

I am trying to create a script that collect a lot of info from VM's and also set info if needed. That is not my problem. The problem is that there is alot of VM's and it takes about 5-8 sec pr VM. I have create a small sample script to run a process on several VM's at the same time, but it fails in mysterious ways If I only allow 1 thread everything is behaving as expected. More than one thread, it fails with messages that states the PowerCLI cmdlet are not known "The term 'Set-PowerCLIConfiguration' is not recognized as the name of a cmdlet"

 

I am using PowerCLI 6

 

Any ideas on whats wrong?

 

 

Below is my sample code (some of it is from Google )

 

# The per VM codeblock sample
$scriptBlock = {  param($VMName, $vcenter, $session)  Write-Host "VMThread - Start for: $($VMName)"  Import-Module VMware.VimAutomation.Core -Global  Write-Host "VMThread - Modules loaded: $(Get-Module)"  $Temp = Set-PowerCLIConfiguration -InvalidCertificateAction Ignore -Scope Session -Confirm:$false  $myVI = Connect-VIServer -Server $vcenter -Session $session  $Myvm = Get-VM -Name $VMName  if($Myvm)  {  Write-Host "VMThread - Getting VM info: $($Myvm.Name)"  $newInfo = New-Object PSObject  $newInfo | Add-Member -Type noteproperty -Name VMName -Value $Myvm.Name  $newInfo | Add-Member -Type noteproperty -Name MemMB -Value $Myvm.MemoryMB  $newInfo  Start-Sleep -Seconds 3  }  else  {  Write-Host "VMThread - No info for VM: $($VMName) - Modules: $(Get-Module)" -ForegroundColor Red  }  Write-Host "VMThread - Done: $($VMName) - Error Count: $($Error.Count) - $Error"
}

#Start the threads and wait for result
function RunTest{
  param  (  $VMs,  $Throttle = 1 #threads  )  process  {  $sessionstate = [System.Management.Automation.Runspaces.InitialSessionState]::CreateDefault()  $sessionstate.ImportPSModule("VMware.VimAutomation.Core")  $RunspacePool = [runspacefactory]::CreateRunspacePool(1, $Throttle, $sessionstate, $Host)  $RunspacePool.Open()  $Jobs = @()  Write-Host "Starting threads.."  foreach ($oneVM in $VMs)  {    $Job = [powershell]::Create().AddScript($ScriptBlock).AddArgument($oneVM.Name).AddArgument($global:DefaultVIServer.Name).AddArgument($global:DefaultVIServer.SessionSecret)    $Job.RunspacePool = $RunspacePool    $Jobs += New-Object PSObject -Property @{RunVM = $_.Name; Pipe = $Job; Result = $Job.BeginInvoke()}  }   Write-Host "Start waiting.."  Do  {    Start-Sleep -Seconds 1  }  While ( $Jobs.Result.IsCompleted -contains $false)  Write-Host "All jobs completed!"   $Results = @()  ForEach ($Job in $Jobs)  {  $Results += $Job.Pipe.EndInvoke($Job.Result)  }  $RunspacePool.Close()  Write-Host "`n`nReturning $($Results.Count) objects..." -ForegroundColor Cyan  $Results  }
}

# Logon to vcenter
$user = Get-Credential domain\user
$vi = connect-viserver myvCenter -Credential $user

$AllVM = Get-VM                     # Return all my VM's, 2 in my test vcenter

RunTest -VMs $AllVM -Throttle 1     # Runs OK, returns one object for each VM

RunTest -VMs $AllVM -Throttle 2     # Fails

Viewing all articles
Browse latest Browse all 175326

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>