VMware Cloud Community
Al_
Enthusiast
Enthusiast

get-vm | get-omresource | sort-object totaldelta

The OMRightsizing function in the script below is from Marcus Krauss. I've added $currentcpu, $currentmem, and $currentmemGB in order to generate a $totaldelta for each VM.  The $totaldelta var is successfully created for each VM, but the sort on $totaldelta is failing: 

[array]$vms2tag = Get-VM -Tag yes | where{(Get-VM -Tag test).Name -Contains $_.Name} | Get-OMResource | Sort-Object TotalDelta -Descending

The object is to rightsize the VMs with the highest $totaldelta first. Here is the script with a sample result below:

Get-Module -Name VMware* -ListAvailable | Import-Module -Force
function Apply-OMRightsizing {
[CmdletBinding()]
param(
[Parameter(Mandatory=$True, ValueFromPipeline=$True, Position=0, HelpMessage = "OM Ressources to process")]
[ValidateNotNullorEmpty()]
$OMResources,
[Parameter(Mandatory=$False, ValueFromPipeline=$False, ParameterSetName="ViewOnly", HelpMessage = "View Recommendations")]
[Switch] $ViewOnly,
[Parameter(Mandatory=$False, ValueFromPipeline=$False, ParameterSetName="Apply", HelpMessage = "Apply Recommendations")]
[Switch] $Apply,
[Parameter(Mandatory=$False, ValueFromPipeline=$False, ParameterSetName="Apply", HelpMessage = "Apply only Downsizing Recommendations")]
[Switch] $NoUpsizing
)
Process {
if ($ViewOnly -or $Apply){
$View = @()
foreach ($OMResource in $OMResources){
$currentcpu = ($OMResource | Get-OMStat -Key "config|hardware|num_Cpu" -From ([DateTime]::Now).AddMinutes(-120) | Select-Object -Last 1).Value
$currentmem = ($OMResource | Get-OMStat -Key "mem|guest_provisioned" -From ([DateTime]::Now).AddMinutes(-120) | Select-Object -Last 1).Value
$currentmemGB = [Math]::Round(($currentmem / 1048576), 0)
$DownSize = ($OMResource | Get-OMStat -Key "summary|oversized" -From ([DateTime]::Now).AddMinutes(-120) | Select-Object -Last 1).Value
$UpSize = ($OMResource | Get-OMStat -Key "summary|undersized" -From ([DateTime]::Now).AddMinutes(-120) | Select-Object -Last 1).Value
# Mem is in KB
if($DownSize -gt 0){
$DownSizeMem = ($OMResource | Get-OMStat -Key "summary|oversized|memory" -From ([DateTime]::Now).AddMinutes(-120) | Select-Object -Last 1).Value
$DownSizeCPU = ($OMResource | Get-OMStat -Key "summary|oversized|vcpus" -From ([DateTime]::Now).AddMinutes(-120) | Select-Object -Last 1).Value
$DownSizeMemGB = [Math]::Round(($DownSizeMem / 1048576), 0)
}
else {
$DownSizeMem = 0
$DownSizeCPU = 0
$DownSizeMemGB = 0
}
# Mem is in KB
if($UpSize -gt 0){
$UpSizeMem = ($OMResource | Get-OMStat -Key "summary|undersized|memory" -From ([DateTime]::Now).AddMinutes(-120) | Select-Object -Last 1).Value
$UpSizeCPU = ($OMResource | Get-OMStat -Key "summary|undersized|vcpus" -From ([DateTime]::Now).AddMinutes(-120) | Select-Object -Last 1).Value
$UpSizeMemGB = [Math]::Round(($UpSizeMem / 1048576), 0)
}
else {
$UpSizeMem = 0
$UpSizeCPU = 0
$UpSizeMemGB = 0
}
if ($DownSizeCPU -gt 0) {
$cpudelta = ($currentcpu - $DownSizeCPU)
}
elseif ($UpSizeCPU -gt 0) {
$cpudelta = ($currentcpu - $UpSizeCPU)
}
else {
$cpudelta = 0
}
if ($DownSizeMemGB -gt 0) {
$memdelta = ($currentmemGB - $DownSizeMemGB)
}
elseif ($UpSizeMemGB -gt 0) {
$memdelta = ($currentmemGB - $UpSizeMemGB)
}
else {
$memdelta = 0
}
$totaldelta = $memdelta + $cpudelta
$Report = [PSCustomObject] @{
Name = $OMResource.name
DownSize = $DownSize
UpSize = $UpSize
DownSizeMem = $DownSizeMem
DownSizeMemGB = $DownSizeMemGB
DownSizeCPU = $DownSizeCPU
UpSizeMem = $UpSizeMem
UpSizeMemGB = $UpSizeMemGB
UpSizeCPU = $upSizeCPU
MemDelta = $memdelta
CPUDelta = $cpudelta
TotalDelta = $totaldelta
}
$View += $Report
#$Report | Select Name,DownSize,UpSize,DownSizeMem,DownSizeMemGB,DownSizeCPU,UpSizeMem,UpSizeMemGB,UpSizeCPU |
#Export-Csv -Path $("D:\temp\rightsized-vms.csv") -NoTypeInformation -UseCulture -Append -Force
}
}
if ($ViewOnly){
$View
}
if ($Apply){
foreach ($Object in $View) {
if ($Object.DownSize -gt 0 -or $Object.UpSize -gt 0){
"Processing '$($Object.Name)' ..."
$VM = Get-VM -Name $Object.Name
"Shut down '$($Object.Name)' ..."
$VM | Shutdown-VMGuest -Confirm:$False
$i = 0
while((Get-VM -Name $VM.Name).PowerState -eq "PoweredOn"){
$i++
Start-Sleep 1
Write-Progress -Activity "Check PowerState" -Status "Wait for PowerState Task..."
}
"Create Snapshot for '$($Object.Name)' ..."
$VM | New-Snapshot -Name "Pre Resize" -Memory:$false -Quiesce:$false
if ($Object.DownSize -gt 0){
"Downsize '$($Object.Name)' ..."
$VM | Set-VM -NumCPU $($VM.NumCpu - $Object.DownSizeCPU) -MemoryGB $($VM.MemoryGB - $Object.DownSizeMemGB) -Confirm:$False
}
if ($Object.UpSize -gt 0 -and $NoUpsizing -eq $False){
"Upsize '$($Object.Name)' ..."
$VM = Get-VM -Name $Object.Name
$VM | Set-VM -NumCPU $($VM.NumCpu + $Object.UpSizeCPU) -MemoryGB $($VM.MemoryGB + $Object.UpSizeMemGB) -Confirm:$False
}
"Power on '$($Object.Name)' ..."
$VM | Start-VM -Confirm:$False
}
}
}
}
}
Get-VICredentialStoreItem -File C:\Users\***********\AppData\Roaming\VMware\credstore\vicredentials.xml | %{
Connect-VIServer -Server $_.host -User $_.User -Password $_.Password}

Get-VICredentialStoreItem -File C:\Users\***********\AppData\Roaming\VMware\credstore\custom\vicredentials.xml | %{
Connect-OMServer -Server $_.host -User $_.User -Password $_.Password}

[array]$vms2tag = Get-VM -Tag yes | where{(Get-VM -Tag test).Name -Contains $_.Name} | Get-OMResource | Sort-Object TotalDelta -Descending
ForEach ($item in $vms2tag) {
$Name = $item.Name
[array]$ToolsStatus = Get-VM -Name $Name | Select Name,@{N="Tools Status";E={$_.ExtensionData.Guest.ToolsStatus}}
ForEach ($object in $ToolsStatus){
$srv = $object.name
$tools = $object."Tools Status"
if ("toolsOk","toolsOld" -contains $tools) {
Write-Host "Rightsizing " $srv, $tools
Get-VM -Name $Name | Get-OMResource | Apply-OMRightsizing -ViewOnly
}
else {Write-Host "Skipping " $srv, $tools}
}
}

Results:
Rightsizing ***tstviewcs toolsOld

Name : ***tstviewcs
DownSize : 1
UpSize : 0
DownSizeMem : 2097152
DownSizeMemGB : 2
DownSizeCPU : 0
UpSizeMem : 0
UpSizeMemGB : 0
UpSizeCPU : 0
MemDelta : 6
CPUDelta : 0
TotalDelta : 6

Rightsizing ***tstviewss toolsOld

Name : ***tstviewss
DownSize : 1
UpSize : 0
DownSizeMem : 1048576
DownSizeMemGB : 1
DownSizeCPU : 0
UpSizeMem : 0
UpSizeMemGB : 0
UpSizeCPU : 0
MemDelta : 3
CPUDelta : 0
TotalDelta : 3

Rightsizing ***-rhel79-test toolsOk

Name : ***-rhel79-test
DownSize : 0
UpSize : 0
DownSizeMem : 0
DownSizeMemGB : 0
DownSizeCPU : 0
UpSizeMem : 0
UpSizeMemGB : 0
UpSizeCPU : 0
MemDelta : 0
CPUDelta : 0
TotalDelta : 0

Rightsizing *******2016test toolsOk

Name : *******2016test
DownSize : 1
UpSize : 0
DownSizeMem : 3145728
DownSizeMemGB : 3
DownSizeCPU : 0
UpSizeMem : 0
UpSizeMemGB : 0
UpSizeCPU : 0
MemDelta : 5
CPUDelta : 0
TotalDelta : 5

 

PS D:\temp> .\arraysort.ps1

Reply
0 Kudos
5 Replies
LucD
Leadership
Leadership

What is

Get-OMResource | Sort-Object TotalDelta -Descending

supposed to do?
Afaik, the objects returned by Get-OMResource do not have a TotalDelta property.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
Al_
Enthusiast
Enthusiast

The object is to rightsize the VMs with the highest $totaldelta first. I generate current CPU and MEM vars and add/subtract from recommended to generate the delta vars. The $totaldelta for each VM is correct. I'm just unable to sort the list of VMs by $totaldelta to rightsize the highest values first.

Reply
0 Kudos
Al_
Enthusiast
Enthusiast

Oh I think I understand your question now: I tried to create TotalDelta in the report section:

$Report = [PSCustomObject] @{
Name = $OMResource.name
DownSize = $DownSize
UpSize = $UpSize
DownSizeMem = $DownSizeMem
DownSizeMemGB = $DownSizeMemGB
DownSizeCPU = $DownSizeCPU
UpSizeMem = $UpSizeMem
UpSizeMemGB = $UpSizeMemGB
UpSizeCPU = $upSizeCPU
MemDelta = $memdelta
CPUDelta = $cpudelta
TotalDelta = $totaldelta

I also tried unsuccessfully sorting on $totaldelta itself like this:

[array]$vms2tag = Get-VM -Tag yes | where{(Get-VM -Tag test).Name -Contains $_.Name} | Get-OMResource | Sort-Object $totaldelta -Descending

Reply
0 Kudos
LucD
Leadership
Leadership

That Sort-Object will not work at all.
You can't reference an array used inside a function, and Sort-Object expects a property in the objects you pipe to it.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
Al_
Enthusiast
Enthusiast

Yes, makes sense. I'll work on a different solution. Thanks.

Reply
0 Kudos