I've looked around and found scripts here and there that can do some of what I need but nothing that can do exactly what I want. Unfortunately, I'm new to Powercli/Powershell so I don't know what I'm doing.
I need a script that can generate CPU and Memory utilization for specific dates and time. For example. 12PM to 5PM on the December 17th. Is this possible and can someone point me to a sample script I can modify?
Thanks in advance.
Perhaps try the following, define a longer period, let's say 7 days.
And then check if any data is returned. Once you have the data, you should have a look at the Timestamp in the returned counters.
$dayEnd = Get-Date
$dayStart = $dayEnd.AddDays(-7)
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
I get the following error after adding your last mod.
Get-Stat : Cannot validate argument on parameter 'Finish'. The argument is null
or empty. Supply an argument that is not null or empty and then try the comman
d again.
At C:\Windows\System32\WindowsPowerShell\v1.0\VMwareReportscripts7.ps1:11 char:
67
+ $stats = Get-Stat -Entity $vm -Stat $stat -Start $dayStart -Finish <<<< $day
End
+ CategoryInfo : InvalidData: (:) [Get-Stat], ParameterBindingVal
idationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,VMware.VimAutom
ation.ViCore.Cmdlets.Commands.GetViStats
-----------------------------------------------
This is what my current script looks like. First line deleted...
$vm = Get-VM | where {$_.PowerState -eq "PoweredOn"}
Write-Output "VMs found $($vm.Count)"
$dayStart = Get-Date
$dayEnd = $dayEnd.AddDays(-7)
Write-Output "From $dayStart"
Write-Output "To $dayEnd"
$stat = 'cpu.usage.average','mem.usage.average'
$stats = Get-Stat -Entity $vm -Stat $stat -Start $dayStart -Finish $dayEnd
$report = $stats | Group-Object -Property {$_.Entity.Name} | %{
New-Object PSObject -Property @{
VM = $_.Name
ESX = $_.Group[0].Entity.Name
Cluster = Get-Cluster -VM $_.Group[0].Entity | Select -ExpandProperty Name
CPUavg = $_.Group | Where {$_.MetricID -eq 'cpu.usage.average'} | Measure-Object -Property Value -Average | Select -ExpandProperty Average
Memavg = $_.Group | Where {$_.MetricID -eq 'mem.usage.average'} | Measure-Object -Property Value -Average | Select -ExpandProperty Average
}
}
$report | Select VM,CPUavg,Memavg |
Export-Csv "C:\report.csv" -NoTypeInformation -UseCulture
You swapped the calculation of the values around, Start should be before Finish in time.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
------------------------ ****** ---------------------------------------- ****** -------------------------------
wrt
Try like this
$stat = 'cpu.usage.average','mem.usage.average'
$stats = Get-Stat -Entity $vm -Stat $stat -Start $dayStart -Finish $dayEnd
$report = $stats | Group-Object -Property {$_.Entity.Name} | %{
New-Object PSObject -Property @{
VM = $_.Name
ESX = $_.Group[0].Entity.Name
Cluster = Get-Cluster -VM $_.Group[0].Entity | Select -ExpandProperty Name
CPUavg = $_.Group | Where {$_.MetricID -eq 'cpu.usage.average'} | Measure-Object -Property Value -Average | Select -ExpandProperty Average
Memavg = $_.Group | Where {$_.MetricID -eq 'mem.usage.average'} | Measure-Object -Property Value -Average | Select -ExpandProperty Average
}
}
------------------------ ****** ---------------------------------------- ****** -------------------------------
ESX = $_.Group[0].Entity.Name
returned the vm name itself
ESX = $_.Group[0].Entity.vmhost | Select -ExpandProperty Name
will do ?
I had to step away from this for a couple of days to work on something else but I'm back to work on it again. I noticed that the initial request wasn't very clear. The current script gives me the average CPU and Memory for a set time frame. For example, 12PM to 3PM I get a table like the following.
VM | CPUavg | Memavg |
---|---|---|
MyVM1 | 23.435345 | 12.656534 |
MyVM2 | 43.554332 | 34.464545 |
MyVM3 | 54.564551 | 65.234232 |
Is it possible to have the script do something like the following: If there's a way to generate against the VM Hos or cluster that will be great, If not, I don't mind generating on each VM.
Time | MemAvgUsage | CPUAvgUsage |
12/9/2014 11:05:00 | 30.99 | 6.01 |
12/9/2014 11:10:00 | 29.99 | 5.8 |
12/9/2014 11:15:00 | 25 | 4.69 |
12/9/2014 11:20:00 | 25.99 | 4.99 |
12/9/2014 11:25:00 | 25.99 | 5.41 |
12/9/2014 11:30:00 | 27.99 | 5.38 |
You mean like this ?
$vm = Get-VM | where {$_.PowerState -eq "PoweredOn"}
Write-Output "VMs found $($vm.Count)"
$dayEnd = Get-Date
$dayStart = $dayEnd.AddDays(-1)
Write-Output "From $dayStart"
Write-Output "To $dayEnd"
$stat = 'cpu.usage.average','mem.usage.average'
$stats = Get-Stat -Entity $vm -Stat $stat -Start $dayStart -Finish $dayEnd
$report = $stats | Group-Object -Property {$_.Entity.Name},Timestamp | %{
New-Object PSObject -Property @{
VM = $_.Name
ESX = $_.Group[0].Entity.Name
Cluster = Get-Cluster -VM $_.Group[0].Entity | Select -ExpandProperty Name
Timestamp = $_.Group[0].Timestamp
CPUavg = $_.Group | Where {$_.MetricID -eq 'cpu.usage.average'} | Select -ExpandProperty Value
Memavg = $_.Group | Where {$_.MetricID -eq 'mem.usage.average'} | Select -ExpandProperty Value
}
}
$report | Select VM,CPUavg,Memavg |
Export-Csv "C:\report.csv" -NoTypeInformation -UseCulture
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Thank you LucD.
That will work for me. I tried to add networking to the script but it returns system.object[] in the Netavg column. Do you know what I'm doing wrong?
$vm = Get-VM | where {$_.PowerState -eq "PoweredOn"}
Write-Output "VMs found $($vm.Count)"
$dayEnd = Get-Date
$dayStart = $dayEnd.AddDays(-1)
Write-Output "From $dayStart"
Write-Output "To $dayEnd"
$stat = 'cpu.usage.average','mem.usage.average','net.usage.average'
$stats = Get-Stat -Entity $vm -Stat $stat -Start $dayStart -Finish $dayEnd
$report = $stats | Group-Object -Property {$_.Entity.Name},Timestamp | %{
New-Object PSObject -Property @{
VM = $_.Name
ESX = $_.Group[0].Entity.Name
Cluster = Get-Cluster -VM $_.Group[0].Entity | Select -ExpandProperty Name
Timestamp = $_.Group[0].Timestamp
CPUavg = $_.Group | Where {$_.MetricID -eq 'cpu.usage.average'} | Select -ExpandProperty Value
Memavg = $_.Group | Where {$_.MetricID -eq 'mem.usage.average'} | Select -ExpandProperty Value
Netavg = $_.Group | Where {$_.MetricID -eq 'net.usage.average'} | Select -ExpandProperty Value
}
}
$report
$report | Select VM,CPUavg,Memavg,Netavg |
Export-Csv "C:\VMreports.csv" -NoTypeInformation -UseCulture
For the network counter there are multiple instances, you can select the 'average' instance.
Netavg = $_.Group | Where {$_.MetricID -eq 'net.usage.average' -and $_.Instance -eq ''} | Select -ExpandProperty Value
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
I modified the following line as suggested but the Netavg column doesn't generate any output. It comes back blank. I wonder if it's because I have multiple Network interfaces for each VM.
Netavg = $_.Group | Where {$_.MetricID -eq 'net.usage.average' -and $_Instance -eq 'average'} | Select -ExpandProperty Value
The Instance value should not be 'average' but an empty string (as in my example).
The average value has an Instance value of ''
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
That's how I did it the first time but that didn't work.
Can you try running with the following line, I would like to check which instances you get.
Netavg = [string]::Join('|',($_.Group | Where {$_.MetricID -eq 'net.usage.average'} | Select -ExpandProperty Instance))
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
VM | CPUavg | Memavg | Netavg |
MyVm001, 12/11/2014 13:23:20 | 13.69 | 14.99 | 4000|vmnic0|vmnic2|vmnic1|vmnic4|vmnic3|vmnic5| |
That's what the report looks like.
That last vertical bar indicates that there is an instance with a blank value.
So the Where-clause I gave earlier should work.
Perhaps you could attach the complete script you are using, there might be a typo perhaps ?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Here's my script.
$vm = Get-VM | where {$_.PowerState -eq "PoweredOn"}
Write-Output "VMs found $($vm.Count)"
$dayEnd = Get-Date
$dayStart = $dayEnd.AddDays(-1)
Write-Output "From $dayStart"
Write-Output "To $dayEnd"
$stat = 'cpu.usage.average','mem.usage.average','net.usage.average'
$stats = Get-Stat -Entity $vm -Stat $stat -Start $dayStart -Finish $dayEnd
$report = $stats | Group-Object -Property {$_.Entity.Name},Timestamp | %{
New-Object PSObject -Property @{
VM = $_.Name
ESX = $_.Group[0].Entity.Name
Cluster = Get-Cluster -VM $_.Group[0].Entity | Select -ExpandProperty Name
Timestamp = $_.Group[0].Timestamp
CPUavg = $_.Group | Where {$_.MetricID -eq 'cpu.usage.average'} | Select -ExpandProperty Value
Memavg = $_.Group | Where {$_.MetricID -eq 'mem.usage.average'} | Select -ExpandProperty Value
Netavg = [string]::join('|',($_.Group | Where {$_.MetricID -eq 'net.usage.average'} | Select -ExpandProperty Instance))
}
}
$report | Select VM,CPUavg,Memavg,Netavg | Sort-Object VM | Export-Csv "C:\temp\VMreports.csv" -NoTypeInformation -UseCulture
Try like this
$vm = Get-VM | where {$_.PowerState -eq "PoweredOn"}
Write-Output "VMs found $($vm.Count)"
$dayEnd = Get-Date
$dayStart = $dayEnd.AddDays(-1)
Write-Output "From $dayStart"
Write-Output "To $dayEnd"
$stat = 'cpu.usage.average','mem.usage.average','net.usage.average'
$stats = Get-Stat -Entity $vm -Stat $stat -Start $dayStart -Finish $dayEnd
$report = $stats | Group-Object -Property {$_.Entity.Name},Timestamp | %{
New-Object PSObject -Property @{
VM = $_.Name
ESX = $_.Group[0].Entity.Name
Cluster = Get-Cluster -VM $_.Group[0].Entity | Select -ExpandProperty Name
Timestamp = $_.Group[0].Timestamp
CPUavg = $_.Group | Where {$_.MetricID -eq 'cpu.usage.average'} | Select -ExpandProperty Value
Memavg = $_.Group | Where {$_.MetricID -eq 'mem.usage.average'} | Select -ExpandProperty Value
Netavg = $_.Group | Where {$_.MetricID -eq 'net.usage.average' -and $_.Instance -eq ''} | Select -ExpandProperty Value
}
}
$report | Select VM,CPUavg,Memavg,Netavg | Sort-Object VM |
Export-Csv "C:\temp\VMreports.csv" -NoTypeInformation -UseCulture
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference