# # Sources: http://www.peetersonline.nl/index.php/vmware/examine-vmware-cpu-ready-times-with-powershell/ # http://powershell.com/cs/blogs/tobias/archive/2009/02/02/xml-part-2-write-add-and-change-xml-data.aspx # # Notes : Written to export VM stats. # Author : Doug Youd # #------------------------------------------------------------------------------------------------------------- #--- Parameters ---------------------------------------------------------------------------------------------- #XML Template $XMLTemplateFile = "C:/tmp/VMachines_TemplateStat.xml" #Output XML File $XMLOutput = "c:/tmp/VMachinesStat.xml" #Use Shortname? $UseShortname = "True" #Interval (in days) $Interval = "30" #--- Main ---------------------------------------------------------------------------------------------------- #Define the XML Template $XMLTemplate = @' '@ $XMLTemplate | Out-File $XMLTemplateFile -encoding UTF8 $XMLVMachines = New-Object XML $XMLVMachines.load($XMLTemplateFile) $XMLVMachine = @($XMLVMachines.VMachines.VMachine)[0] #Define the stats interval $IntervalFinish = Get-Date $IntervalStart = $IntervalFinish.addDays(-1 * $Interval) #Get list of VM and ESXHost objects for vCenter ForEach ($VMHost in (Get-VMHost)) { foreach($vm in ($VMHost | Get-VM | where {$_.PowerState -ne "PoweredOff"} | Sort Name)){ $Temp = "" | Select-Object Match #Define a custom VMachine PSObject $VMachine = $XMLVMachine.Clone() #Populate Basic VM Info If($UseShortname -eq "True"){ $Temp.Match = $vm.Name -match '^[a-zA-Z0-9\-]*' If($Temp.Match) { $VMachine.VMName = [String]$matches[0] }else { $VMachine.VMName = [String]$vm.Name } }else { $VMachine.VMName = [String]$vm.Name } $VMachine.VMMem = [String]$vm.memorySizeMB $VMachine.VMCpu = [String]$vm.numCpu #Get-stats #Can only get Ready Info on Realtime (unfortunately) $Ready = $vm | Get-Stat -Stat Cpu.Ready.Summation -RealTime -ErrorAction SilentlyContinue $Used = $vm | Get-Stat -Stat Cpu.Used.Summation -RealTime -ErrorAction SilentlyContinue $Wait = $vm | Get-Stat -Stat Cpu.Wait.Summation -RealTime -ErrorAction SilentlyContinue #At defaul stats levels, only able to get Avg rollup. $AvgMhz = $vm | Get-Stat -Stat Cpu.usagemhz.average -Start $IntervalStart -Finish $IntervalFinish -ErrorAction SilentlyContinue $MaxMhz = $vm | Get-Stat -Stat Cpu.usagemhz.maximum -Start $IntervalStart -Finish $IntervalFinish -ErrorAction SilentlyContinue $AvgMemGranted = $vm | Get-Stat -Stat Mem.granted.average -Start $IntervalStart -Finish $IntervalFinish -ErrorAction SilentlyContinue $MaxMemGranted = $vm | Get-Stat -Stat Mem.granted.maximum -Start $IntervalStart -Finish $IntervalFinish -ErrorAction SilentlyContinue $AvgMemActive = $vm | Get-Stat -Stat Mem.active.average -Start $IntervalStart -Finish $IntervalFinish -ErrorAction SilentlyContinue $MaxMemActive = $vm | Get-Stat -Stat Mem.active.maximum -Start $IntervalStart -Finish $IntervalFinish -ErrorAction SilentlyContinue $AvgDiskIO = $vm | Get-Stat -Stat disk.usage.average -Start $IntervalStart -Finish $IntervalFinish -ErrorAction SilentlyContinue $MaxDiskIO = $vm | Get-Stat -Stat disk.usage.maximum -Start $IntervalStart -Finish $IntervalFinish -ErrorAction SilentlyContinue $AvgNetIO = $vm | Get-Stat -Stat net.usage.average -Start $IntervalStart -Finish $IntervalFinish -ErrorAction SilentlyContinue $MaxNetIO = $vm | Get-Stat -Stat net.usage.maximum -Start $IntervalStart -Finish $IntervalFinish -ErrorAction SilentlyContinue #Populate Per-VM Stats $VMachine.Stats.Cpu.AvgMhz = [String]([Math]::Round((($AvgMhz | Measure-Object -Property Value -Average).Average),1)) $VMachine.Stats.Cpu.MaxMhz = [String]([Math]::Round((($MaxMhz | Measure-Object -Property Value -Average).Average),1)) $VMachine.Stats.Memory.AvgMemGranted = [String]([Math]::Round((($AvgMemGranted | Measure-Object -Property Value -Average).Average),1)) $VMachine.Stats.Memory.MaxMemGranted = [String]([Math]::Round((($MaxMemGranted | Measure-Object -Property Value -Average).Average),1)) $VMachine.Stats.Memory.AvgMemActive = [String]([Math]::Round((($AvgMemActive | Measure-Object -Property Value -Average).Average),1)) $VMachine.Stats.Memory.MaxMemActive = [String]([Math]::Round((($MaxMemActive | Measure-Object -Property Value -Average).Average),1)) $VMachine.Stats.Disk.AvgDiskIo = [String]([Math]::Round((($AvgDiskIo | Measure-Object -Property Value -Average).Average),1)) $VMachine.Stats.Disk.MaxDiskIo = [String]([Math]::Round((($MaxDiskIo | Measure-Object -Property Value -Average).Average),1)) $VMachine.Stats.Network.AvgNetIo = [String]([Math]::Round((($AvgNetIo | Measure-Object -Property Value -Average).Average),1)) $VMachine.Stats.Network.MaxNetIo = [String]([Math]::Round((($MaxNetIo | Measure-Object -Property Value -Average).Average),1)) #Populate per-vCPU Stats For ($a = 0; $a -lt $VM.NumCpu; $a++) { #Create a new CPU instance $VCpu = (@($VMachine.Stats.Cpu.VCPUs.VCpu)[0]).Clone() $VCpu.Instance = [String]$a $VCpu.CpuRdy = [String]([Math]::Round((($Ready | Where {$_.Instance -eq $a} | Measure-Object -Property Value -Average).Average)/200,1)) $VCpu.CpuUsed = [String]([Math]::Round((($Used | Where {$_.Instance -eq $a} | Measure-Object -Property Value -Average).Average)/200,1)) $VCpu.CpuWait = [String]([Math]::Round((($Wait | Where {$_.Instance -eq $a} | Measure-Object -Property Value -Average).Average)/200,1)) $VCpu.AvgMhz = [String]([Math]::Round((($AvgMhz | Where {$_.Instance -eq $a} | Measure-Object -Property Value -Average).Average),1)) $VCpu.MaxMhz = [String]([Math]::Round((($MaxMhz | Where {$_.Instance -eq $a} | Measure-Object -Property Value -Average).Average),1)) $VMachine.Stats.Cpu.VCpus.AppendChild($VCpu) > $null } #Clear the variables. Clear-Variable Ready -ErrorAction SilentlyContinue Clear-Variable Wait -ErrorAction SilentlyContinue Clear-Variable Used -ErrorAction SilentlyContinue Clear-Variable CpuMhz -ErrorAction SilentlyContinue Clear-Variable AvgMemGranted -ErrorAction SilentlyContinue Clear-Variable MaxMemGranted -ErrorAction SilentlyContinue Clear-Variable AvgMemActive -ErrorAction SilentlyContinue Clear-Variable MaxMemActive -ErrorAction SilentlyContinue Clear-Variable AvgDiskIo -ErrorAction SilentlyContinue Clear-Variable MaxDiskIo -ErrorAction SilentlyContinue Clear-Variable AvgNetIo -ErrorAction SilentlyContinue Clear-Variable MaxNetIo -ErrorAction SilentlyContinue #Clear Blank CPU Instances $VMachine.Stats.Cpu.VCpus.VCpu | Where-Object {$_.Instance -eq ""} | ForEach-Object {[Void]$VMachine.Stats.Cpu.VCpus.RemoveChild($_)} #Add VM to VMachines array $XMLVMachines.VMachines.AppendChild($VMachine) > $null } } #Clear blank VMs $VMachines.VMachines.VMachine | Where-Object {$_.VMName -eq ""} | ForEach-Object {[Void]$VMachines.VMachines.RemoveChild($_)} #Export to XML $XMLVMachines.Save($XMLOutput)