0

I am trying to collect performance data from vcenter for hosts. I've created this powershell script. It works but it takes a extremely long time to complete. Is there a better more efficient way to retrieve data from vcenters.

Connect-VIServer "vcenter.server.com" -User user123 -Password testpassword
$allvms = @()
$allhosts = @()
$hosts = Get-VMHost
$vms = Get-Vm

foreach($vmHost in $hosts){
  $hoststat = "" | Select HostName, MemMax, MemAvg, MemMin, CPUMax, CPUAvg, CPUMin
  $hoststat.HostName = $vmHost.name

  $statcpu = Get-Stat -Entity ($vmHost)-start (get-date).AddDays(-1) -Finish (Get-Date)-MaxSamples 10 -stat cpu.usage.average
  $statmem = Get-Stat -Entity ($vmHost)-start (get-date).AddDays(-1) -Finish (Get-Date)-MaxSamples 10 -stat mem.usage.average

  $cpu = $statcpu | Measure-Object -Property value -Average -Maximum -Minimum
  $mem = $statmem | Measure-Object -Property value -Average -Maximum -Minimum

  $hoststat.CPUMax = $cpu.Maximum
  $hoststat.CPUAvg = $cpu.Average
  $hoststat.CPUMin = $cpu.Minimum
  $hoststat.MemMax = $mem.Maximum
  $hoststat.MemAvg = $mem.Average
  $hoststat.MemMin = $mem.Minimum
  $allhosts += $hoststat
}
$allhosts | Select HostName, MemMax, MemAvg, MemMin, CPUMax, CPUAvg, CPUMin | Export-Csv "c:\output\Hosts.csv" -noTypeInformation
user1471980
  • 10,127
  • 48
  • 136
  • 235
  • Have you considered using PowerShell jobs? You could create a background job for each VM host. –  Aug 20 '14 at 21:27
  • @TrevorSullivan, I even nailed down to one esx host within vcenter, it takes considerable time. Do you have an example jobs there you're referring to? – user1471980 Aug 20 '14 at 21:30
  • You can put all the code inside the `foreach` loop into a call to `Start-Job`. That way, you run a single background job for each VM host, instead of running all of the code synchronously. At the end of the script, you can use `Wait-Job` to wait for all the jobs to complete, and then aggregate the results together. –  Aug 20 '14 at 21:32

2 Answers2

1

Consider the following code, which moves the processing into a PowerShell background job:

Connect-VIServer "vcenter.server.com" -User user123 -Password testpassword
$allvms = @()
$allhosts = @()
$hosts = Get-VMHost;
$vms = Get-Vm;

# Define the code that will be executed as part of the background job
$Job = {
  $hoststat = @{};

  $statcpu = Get-Stat -Entity $args[0] -start (get-date).AddDays(-1) -Finish (Get-Date)-MaxSamples 10 -stat cpu.usage.average;
  $statmem = Get-Stat -Entity $args[0] -start (get-date).AddDays(-1) -Finish (Get-Date)-MaxSamples 10 -stat mem.usage.average;

  $cpu = $statcpu | Measure-Object -Property value -Average -Maximum -Minimum;
  $mem = $statmem | Measure-Object -Property value -Average -Maximum -Minimum;

  $hoststat.HostName = $args[0];
  $hoststat.CPUMax = $cpu.Maximum;
  $hoststat.CPUAvg = $cpu.Average;
  $hoststat.CPUMin = $cpu.Minimum;
  $hoststat.MemMax = $mem.Maximum;
  $hoststat.MemAvg = $mem.Average;
  $hoststat.MemMin = $mem.Minimum;

  return $hoststat;
}

$JobList = @();
foreach($vmHost in $hosts){
    $JobList += Start-Job -ScriptBlock $Job -Name $vmHost.Name -ArgumentList $vmHost.Name;
}

Wait-Job -Job $JobList;
$JobList | % { $allhosts += Receive-Job -Job $PSItem; };
$allhosts | Select HostName, MemMax, MemAvg, MemMin, CPUMax, CPUAvg, CPUMin | Export-Csv "c:\output\Hosts.csv" -noTypeInformation
1

You could collect multiple metrics from multiple host entities with a single get-stat call, as in,

get-stat -Entity $hosts -MaxSamples 10 -Stat "cpu.usage.average","mem.usage.average"

and then use Group-Object to parse the results. LucD's posts here might be helpful.

I wonder if you need $vms = Get-Vm because the code you posted does not refer back to that.

Your PS session should be on the same LAN with the vcenter db. See also kb.vmware.com/kb/2007388.

noam
  • 1,914
  • 2
  • 20
  • 26
  • get-stat command is taking a very long time. Do you know of any other way to get perfromance data from vcenters the quick way? – user1471980 Aug 21 '14 at 14:19
  • Not offhand, but an API might not help if queries to the vcenter db are performing poorly. See updated answer. – noam Aug 21 '14 at 19:02
  • creating powershell script to pull data from vcenters take a very long time, I haven't seen it completed sucessfully so far. I am curious is there any other way? – user1471980 Aug 22 '14 at 15:17