Al_
Enthusiast
Enthusiast

Sort VM list and apply function based on tools status fails

($vms2rs = Get-VM -Tag yes | where{(Get-VM -Tag test).Name -Contains $_.Name}).Name
$data = ForEach ($item in $vms2rs) {
$Name = $item.Name
Get-VM -Name $Name | Get-OMResource |
Get-OMStat -Key "Super Metric|sm_6dcf4b1d-fa56-4119-bef8-b197df54b70a" -From ([DateTime]::Now).AddMinutes(-120) |
Select-Object @{N='VM';E={$name}},Resource, Value -Last 1
}
$data | Sort-Object -Property Value -Descending | Select VM

ForEach ($item in $data) {
$Name = Resource???
$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-CustomFunction 
}
else {Write-Host "Skipping " $srv, $tools}
}
}

0 Kudos
6 Replies
Al_
Enthusiast
Enthusiast

should I maybe perform tools status check and apply CustomFunction in the $data for loop?

0 Kudos
Al_
Enthusiast
Enthusiast

I tried this but no luck:

($vms2rs = Get-VM -Tag yes | where{(Get-VM -Tag test).Name -Contains $_.Name}).Name
$data = ForEach ($item in $vms2rs) {
$Name = $item.Name
$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
$vm = Get-VM -Name $Name | Get-OMResource |
Get-OMStat -Key "Super Metric|sm_6dcf4b1d-fa56-4119-bef8-b197df54b70a" -From ([DateTime]::Now).AddMinutes(-120) |
Select-Object @{N='VM';E={$name}},Resource, Value -Last 1 | Sort-Object -Property Value -Descending |
Apply-OMRightsizing -ViewOnly
}
}

else {Write-Host "Skipping " $srv, $tools}

}

0 Kudos
Dharzhak
Contributor
Contributor

If I'm reading this right, you're just wanting to perform "Get-VM -Name $Name | Get-OMResource | Apply-CustomFunction" on VMs that have a tools status of "toolsOk" or"toolsOld", correct?

If so, probably close to the most efficient way would be to use Get-View and just select the properties you care about, so you're not loading up the entirety of the extension data for every VM on the vCenter.

$VMViews = Get-View -ViewType VirtualMachine -Property Name,Guest.ToolsStatus | Where-Object {$_.Guest.ToolsStatus -in "toolsOk","toolsOld"}
Get-VM -Name $VMViews.Name | Get-OMResource | Apply-CustomFunction

0 Kudos
Al_
Enthusiast
Enthusiast

Hi Dharzhak, sorry for the delay. Thanks for the Get-View example. I might have to change my script to use it, but I may not have stated the desired solution fully. The goal is to get a list of VMs from vCenter based on a combination of tags, Check the tools status and then get only VMs with toolsOk or toolsOld, skip the rest, then get an OMStat Key for a custom supermetric, and sort the list of VMs based on the supermetric, then apply the rightsizing function. LucD has helped me extensively with everything here, to the point that my script can do everything except check and rightsize or skip based on tools status. I didn't include the tools status requirement earlier as I was working on each component individually and putting them together. I had a method to do the tools check in a different script, so I attempted to add it here. Everything is working, except now the sort on supermetric seems broken:

($vms2rs = Get-VM -Tag yes | where{(Get-VM -Tag test).Name -Contains $_.Name}).Name
$data = ForEach ($item in $vms2rs) {
$Name = $item.Name
$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) {
$vm = Get-VM -Name $Name | Get-OMResource |
Get-OMStat -Key "Super Metric|sm_6dcf4b1d-fa56-4119-bef8-b197df54b70a" -From ([DateTime]::Now).AddMinutes(-120) |
Select-Object @{N='VM';E={$name}},Resource, Value -Last 1 | Sort-Object -Property Value -Descending
#| Apply-OMRightsizing -ViewOnly
Write-Host "Rightsizing " $Name, $tools
}
}
}

incorrectly returns:
Rightsizing rhel79-test toolsOk
Rightsizing 2016test toolsOk
Rightsizing tstviewcs toolsOld
Rightsizing tstviewss toolsOld

sorted by supermetric value would be this order:
@{VM=tstviewcs; Resource=tstviewcs; Value=6}
@{VM=2016test; Resource=2016test; Value=5}
@{VM=tstviewss; Resource=tstviewss; Value=3}
@{VM=-rhel79-test; Resource=-rhel79-test; Value=2}

everything was working, I tried to add in the tools piece, now broken.

 

0 Kudos
Al_
Enthusiast
Enthusiast

This was the script LucD helped me with before I tried to add in the tools check piece. It works correctly and returna a list of VMs in the correctly sorted order. I just need to add in a tools check on the VMs somewhere before I apply a rightsizing function:

($vms2rs = Get-VM -Tag yes | where{(Get-VM -Tag test).Name -Contains $_.Name}).Name
$data = ForEach ($item in $vms2rs) {
$Name = $item.Name
Get-VM -Name $Name | Get-OMResource |
Get-OMStat -Key "Super Metric|sm_6dcf4b1d-fa56-4119-bef8-b197df54b70a" -From ([DateTime]::Now).AddMinutes(-120) |
Select-Object @{N='VM';E={$name}},Resource, Value -Last 1
}
$data | Sort-Object -Property Value -Descending | Select VM

returns in correctly sorted order:
VM : tstviewcs
VM : 2016test
VM : tstviewss
VM : rhel79-test

0 Kudos
Al_
Enthusiast
Enthusiast

I tried this:

($vms2rs = Get-VM -Tag yes | where{(Get-VM -Tag test).Name -Contains $_.Name}).Name -and Where{$_.Guest.ToolsStatus -in "toolsOk","toolsOld"}

but it throws this error:

+ ... | where{(Get-VM -Tag test).Name -Contains $_.Name}).Name -and Where{$ ...
+ ~
You must provide a value expression following the '-and' operator.
At line:1 char:90

0 Kudos