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 :smileycry: 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"
# 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