We have a training VCenter which we run courses for students.
We have a datacenter containing resource pools for each course we run. Each resource pool contains multiple VMs relevant to the course.
We have another datacenter which contains the hosts we deploy student environments to. Each student environment is contained in a resource pool.
I need to create a Powercli script which would calculate the percentage of free storage, cpu and memory left on each host if we deployed a course.
For example.
Course is starting with 6 students and I have provisioned 3 hosts for this course. 2 student environments per host.
Prior to deploying the VMs I want to check if my hosts can accommodate all the VMs by making sure there is atleast x percentage of Storage, Memory and CPU
I have started writing a script to do a storage check however I' am not getting accurate results and when deploying all student environments to a single host I get the error below the script.
SCRIPT
param($folder, $resourcePool, $students)
Function Percentcal {
param(
[parameter(Mandatory = $true)]
[int]$InputNum1,
[parameter(Mandatory = $true)]
[int]$InputNum2)
$size = (get-vm -location $resourcePool | get-harddisk | measure-object -property capacityGB -sum | select-object -ExpandProperty sum)
$realsize = [math]::Round($size*1024)
$totalsize = $realsize*$students
$totalvmhosts = $hosts.count
$sizeperhost = $totalsize / $totalvmhosts
$realsizeperhost = [math]::Round($sizeperhost)
$actualfreespace = $InputNum1-$realsizeperhost
$actualfreespace / $InputNum2*100
}
$hosts = Get-VMHost -Location $folder
ForEach ($vhost in $hosts)
{
$ds = Get-Datastore -VMHost $vhost | Where-Object {$_.Name -like "datastore*"} | Sort Name
if ($ds.Name)
{
$PercentFree = Percentcal $ds.FreeSpaceMB $ds.CapacityMB
$PercentFree = "{0:N2}" -f $PercentFree
$ds | Add-Member -type NoteProperty -name PercentFree -value $PercentFree
}
if([int]$PercentFree -gt 5){
Write-Host -ForegroundColor "Yellow" ("Storage on $vhost is OK ")
}
else {
Write-Host -ForegroundColor "Red" ("Storage on $vhost is Insufficient ")
}
}
$ds | Select Name,FreeSpaceMB,CapacityMB,PercentFree | Export-Csv c:\Scripts\Dev\datastorereport.csv -NoTypeInformation
ERROR
Cannot convert value "-Infinity" to type "System.Int32". Error: "Input string was not in a correct
format."
At C:\Scripts\Dev\StorageCheck.ps1:29 char:23
+ if([int]$PercentFree <<<< -gt 5){
+ CategoryInfo : NotSpecified: (:) [], RuntimeException
+ FullyQualifiedErrorId : RuntimeException
You seem to end up with negative infinity in the $PercentFree variable.
That is most probably due to a division by zero somewhere.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Thanks I will have a look at where division of zero is occurring.
Would you know how to script something similar for Memory and CPU.
Thanks.
For memory you could do something like the following.
Mind, I don't really think that assigned memory is a good criteria, I would rather see what a VM is actively using.
$vms = Get-VM | where{$_.PowerState -eq 'PoweredOn'}
$vmMem = $vms | Measure-Object -Property MemoryGB -Sum | Select -ExpandProperty Sum
$esxMem = $vms | Measure-Object -Property {$_.VMHost.MemoryTotalGB} -Sum | select -ExpandProperty Sum
$memPercent = $vmMem/$esxMem*100
For CPU is a bit more tricky.
Do you just count the number of assigned vCPU over the number of available vCPU over all the hosts ?
If yes, then you could use something similar to the memory.
A better, in my opinion, method would be to look again what these VMs are actually using (in MHz).
And then take the percentage from the available MHz over all the ESXi nodes.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
I agree however the VMs are powered off so retrieving the VMs memory/cpu usage is not possible.
The script seems to get a percentage of available memory on the host the VMs are currently residing on.
However I would like to know if I were to clone my VMs onto other hosts how much free memory would be left on each of those hosts.
Kind of like a pre-flight check to make sure we do not consume all the resources when deploying VMs.
Also $esxMem stores total host memory, is there a way or a property which returns free memory.
Thanks
When you do a Get-VMHost, you get the properties MemoryTotalGB and MemoryUsageGB.
That should allow you determine the free/available physical memory
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Thanks for the info.
I have written the script below however I get an error 'Attempted to divide by zero' on line 14 which is calculating $memPercent.
Param($resourcePool, $students, $folder)
$vms = Get-VM -Location $resourcePool
$vmhosts = Get-VMHost -Location $folder
$vmMem = $vms | Measure-Object -Property MemoryGB -Sum | Select -ExpandProperty Sum
$totalvmMem = $vmMem*$students
foreach ($esxhost in $vmhosts) {
$totalMem = [math]::Round($_.MemoryTotalGB)
$usedMem = [math]::Round($_.MemoryUsageGB)
$freeMem = [math]::Round($_.MemoryTotalGB - $_.MemoryUsageGB)
$memPercent = $totalvmMem/$freeMem*100
if([int]$memPercent -gt 10){
Write-Host -ForegroundColor "Yellow" ("Memory on $esxhost is OK ")
}
else {
Write-Host -ForegroundColor "Red" ("Memory on $esxhost is Insufficient ")
}
}
You should be using $esxhost, not the pipeline variable
Param($resourcePool, $students, $folder)
$vms = Get-VM -Location $resourcePool
$vmhosts = Get-VMHost -Location $folder
$vmMem = $vms | Measure-Object -Property MemoryGB -Sum | Select -ExpandProperty Sum
$totalvmMem = $vmMem*$students
foreach ($esxhost in $vmhosts) {
$totalMem = [math]::Round($esxhost.MemoryTotalGB)
$usedMem = [math]::Round($esxhost.MemoryUsageGB)
$freeMem = [math]::Round($esxhost.MemoryTotalGB - $esxhost.MemoryUsageGB)
$memPercent = $totalvmMem/$freeMem*100
if([int]$memPercent -gt 10){
Write-Host -ForegroundColor "Yellow" ("Memory on $esxhost is OK ")
}
else {
Write-Host -ForegroundColor "Red" ("Memory on $esxhost is Insufficient ")
}
}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Thanks that resolved the issue.
How would I do the same for assigned vCPUs over available vCPUs.
I tried running Get-VMHost -Name hostname | Select Name, NumvCPUs.
However NumvCPUs column is blank.
I get the same result with Get-VM.
Thanks
You could do.
Get-VMHost | %{$_.ExtensionData.Hardware.CpuInfo.NumCpuThreads} | Measure-Object -Sum
For the VMs you can do
Get-VM | Measure-Object -Property NumCpu -Sum
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference