I have put a script together to look at certain resource pools and based on their over subscription ratio I assign limits to their resource pool. (i.e. Dev_Pool is 4:1 so for 20 VMs w/ 2 vCPU each, it will set a limit of 10vCPU for the entire pool). The problem I am running in to is that we will have the same resource pool on multiple clusters inside vCenter due to the current cluster maximums (32 hosts). How could I get my script to look at all resource pools inside vCenter and make its calculations based off of the cluster that specific resource pool resides on? I pasted the script below. I welcome any constructive criticism since this is my first real script.
[CmdletBinding()]
param(
[String]$vCenterIPorFQDN="vcenter.xxxxx.com",
[String]$vCenterUsername="XXXXX",
[String]$vCenterPassword="XXXXX"
) # param
Add-PSSnapin VMware.VimAutomation.Core
Connect-VIServer -Server $vCenterIPorFQDN
#Variables
$ODDOverSubRatio = 4
$DROverSubRatio = 8
#Calculates Speed of a single vCPU in MHZ for vCenter
$vCenterPCPUCores = (Get-VMhost -Location * | Measure-object -Property NumCPU -Sum).Sum
$vCenterPCPUMhz = (Get-VMhost -Location * | Measure-object -Property CPUTotalMhz -Sum).Sum
$vCenterVCPU = $vCenterPCPUCores*2
[Int]$SingleCoreMhz = $vCenterPCPUMhz/$vCenterVCPU
#Collectss ODD Pool current resource usage and calculates Resource Pool Limit based on Over Subscription Ration established
$ODDPoolMEM = (Get-ResourcePool -Name ODD | Get-VM | Measure-object -Property MEMoryGB -Sum).Sum
$ODDPoolVCPU = (Get-ResourcePool -Name ODD | Get-VM | Measure-object -Property NumCPU -Sum).Sum
$ODDPoolMEMLimit = $ODDPoolMEM/$ODDOverSubRatio
$ODDPoolVCPULimit=$ODDPoolVCPU/$ODDOverSubRatio
[Int]$ODDPoolVMhzLimit = $ODDPoolVCPU/$ODDOverSubRatio * $SingleCoreMhz
$dataOut = @()
$dataOut += [PScustomObject] @{
Env="ODD Pool"
ODD_Allocated_vCPU=$ODDPoolVCPU
ODD_Pool_CPU_LIMIT=$ODDPoolVCPULimit
ODD_Allocated_MEM=$ODDPoolMEM
ODD_Pool_MEM_LIMIT=$ODDPoolMEMLimit
}
$dataOut
$dataOut | Out-GridView -PassThru -Title "Select OK to continue with these settings"
#Collects DR Pool current resource usage and calculates Resource Pool Limit based on Over Subscription Ration established
$DRPoolMEM = (Get-ResourcePool -Name DR | Get-VM | Measure-object -Property MEMoryGB -Sum).Sum
$DRPoolVCPU = (Get-ResourcePool -Name DR | Get-VM | Measure-object -Property NumCPU -Sum).Sum
$DRPoolMEMLimit = $DRPoolMEM/$DROverSubRatio
$DRPoolVCPULimit= $DRPoolVCPU/$DROverSubRatio
[Int]$DRPoolVMhzLimit = $DRPoolVCPU/$DROverSubRatio * $SingleCoreMhz
$dataOut = @()
$dataOut += [PScustomObject] @{
Env="DR Pool"
DR_Allocated_vCPU=$DRPoolVCPU
DR_Pool_CPU_LIMIT=$DRPoolVCPULimit
DR_Allocated_MEM=$DRPoolMEM
DR_Pool_MEM_LIMIT=$DRPoolMEMLimit
}
$dataOut
$dataOut | Out-GridView -PassThru -Title "Select OK to continue with these settings"
#Collects IaaS Pool current resource usage and calculates Resource Pool Reservation based on current allocated resources
[Int]$IaaSPoolMEM = (Get-ResourcePool -Name IaaS_Pool | Get-VM | Measure-object -Property MEMoryGB -Sum).Sum
$IaaSPoolVCPU = (Get-ResourcePool -Name IaaS_Pool | Get-VM | Measure-object -Property NumCPU -Sum).Sum
[Int]$IaaSPoolMhzRes = $IaaSPoolVCPU * $SingleCoreMhz
$dataOut = @()
$dataOut += [PScustomObject] @{
Env="Prod Pool"
Prod_Allocated_vCPU=$IaaSPoolVCPU
Prod_Allocated_MEM=$IaaSPoolMEM
}
$dataOut
$dataOut | Out-GridView -PassThru -Title "Select OK to continue with these settings"
#Set-ResourcePool -Resourcepool IaaS_Pool -MemReservationGB $IaaSPoolMEM -CpuReservationMhz $IaaSPoolMhzRes
#Set-ResourcePool -Resourcepool DR -MEMLimitGB $DRPoolMEMLimit -CPULimitMhz $DRPoolVMhzLimit -MemReservationGB 0 -CpuReservationMhz 0
#Set-ResourcePool -Resourcepool ODD -MEMLimitGB $ODDPoolMEMLimit -CPULimitMhz $ODDPoolVMhzLimit -MemReservationGB 0 -CpuReservationMhz 0
Disconnect-VIServer -Server $vCenterIPorFQDN
You could basically try something along these lines.
Loop through all the clusters, and then loop through all the resourcepools.
I used a subscriptionratio lookup table at the beginning, you can add resourcepools and their ratio in there.
$ratios = @{
'ODD' = 4
'DR' = 8
}
$dataOut = @()
foreach($cluster in Get-Cluster){
#Calculates Speed of a single vCPU in MHZ for Cluster
$clusterPCPUCores = (Get-VMhost -Location $cluster | Measure-object -Property NumCPU -Sum).Sum
$clusterPCPUMhz = (Get-VMhost -Location $cluster | Measure-object -Property CPUTotalMhz -Sum).Sum
$clusterVCPU = $clusterPCPUCores*2
[Int]$SingleCoreMhz = $clusterPCPUMhz/$clusterVCPU
foreach($rp in Get-ResourcePool -Location $cluster){
$rpMEM = (Get-VM -Location $rp | Measure-object -Property MemoryGB -Sum).Sum
$rpVCPU = (Get-VM -Location $rp | Measure-object -Property NumCPU -Sum).Sum
$rpMEMLimit = $rpMEM/$ratios[$rp.Name]
$rpVCPULimit=$rpVCPU/$ratios[$rp.Name]
[Int]$rpVMhzLimit = $rpVCPU/$ratios[$rp.Name] * $SingleCoreMhz
$dataOut += [PScustomObject] @{
Cluster = $cluster.Name
Env=$rp.Name
Allocated_vCPU=$rpVCPU
Pool_CPU_LIMIT=$rpVCPULimit
Allocated_MEM=$rpMEM
Pool_MEM_LIMIT=$rpMEMLimit
}
}
}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
I am getting a lot of errors related to not being able to divide by zero. I am thinking its because its parsing all Resource Pools and if there is no entry in the $ratios array then it gives it a zero. Is there a way to have it ignore any pools beyond the ones we would specify?
Sure, check for the existence of the key in the table.
$ratios = @{
'ODD' = 4
'DR' = 8
}
$dataOut = @()
foreach($cluster in Get-Cluster){
#Calculates Speed of a single vCPU in MHZ for Cluster
$clusterPCPUCores = (Get-VMhost -Location $cluster | Measure-object -Property NumCPU -Sum).Sum
$clusterPCPUMhz = (Get-VMhost -Location $cluster | Measure-object -Property CPUTotalMhz -Sum).Sum
$clusterVCPU = $clusterPCPUCores*2
[Int]$SingleCoreMhz = $clusterPCPUMhz/$clusterVCPU
foreach($rp in Get-ResourcePool -Location $cluster){
if($ratios.ContainsKey($rp.Name)){
$rpMEM = (Get-VM -Location $rp | Measure-object -Property MemoryGB -Sum).Sum
$rpVCPU = (Get-VM -Location $rp | Measure-object -Property NumCPU -Sum).Sum
$rpMEMLimit = $rpMEM/$ratios[$rp.Name]
$rpVCPULimit=$rpVCPU/$ratios[$rp.Name]
[Int]$rpVMhzLimit = $rpVCPU/$ratios[$rp.Name] * $SingleCoreMhz
$dataOut += [PScustomObject] @{
Cluster = $cluster.Name
Env=$rp.Name
Allocated_vCPU=$rpVCPU
Pool_CPU_LIMIT=$rpVCPULimit
Allocated_MEM=$rpMEM
Pool_MEM_LIMIT=$rpMEMLimit
}
}
else{
Write-Host "No ratio entry for $($cluster.Name/$($rp.Name))"
}
}
}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Thanks a lot for the help, I am getting one error below. If there is no entry in the ratio table it gives it value of zero and then can't divide it. I can just remove the line but I wasn't sure what the $($rp.Name) was supposed to display.
Write-Host "No ratio entry for $($cluster.Name/$($rp.Name))"
No ratio entry for
Cannot convert value "Primary Cluster" to type "System.Int32". Error: "Input string was not in a correct format."
At line:47 char:62
+ ... Write-Host "No ratio entry for $($cluster.Name/$($rp.Name))"
+ ~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvalidCastFromStringToInteger
That's due to the use of the '/' character, PS tries to do a division.
Change '/' to another character, for example a blank.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference