skip to Main Content

I’m trying to make a script that outputs the last 30 values of the performance counter for the Hyper Virtual processors.

reference: https://blogs.technet.microsoft.com/neales/2016/10/24/hyper-v-performance-cpu/
-> Virtual Machine Processor Usage and this for Every VM on The hyper V machine.

I tried moving the echo around, but it does not give me all the good values.
Can anyone shine a light with me?

$vms = Get-VM | Where { $_.State –eq ‘Running’ }

Foreach ( $vm in $vms ) {
   Write-Host 'Status: {0} `n ---------- `n' $vm.Name
   $processors = Get-VMProcessor -VMName $vm.Name
   Foreach ( $processor in $processors ) {
      Write-Host '{0}: `n' $processor.Count
      $procCount = $processor.Count 
      for($i = 0 ; $i -le $procCount; $i++){
          $fullcounter = "\" + $env:computername + "Hyper-V Hypervisor Virtual Processor(" + $vm.Name + ":Hv VP " + $i + ")% Guest Run Time"
          $ret = Get-Counter -Counter $fullcounter -SampleInterval 1 -MaxSamples 30 `
                 | Select-Object -ExpandProperty CounterSamples `
               | Group-Object -Property InstanceName `
               | ForEach-Object { 
                  $_ | Select-Object -Property Name, @{n='Average';e= {($_.Group.CookedValue | Measure-Object -Average).Average}};
                }
         Write-Host "Counter average: $ret"
      }
   }
}

the output I get is:

Status: {0} `n ---------- `n CenTOS
{0}: `n 2
Counter average: @{Name=centos:hv vp 0; Average=13.1989705068454}
Counter average: @{Name=centos:hv vp 1; Average=12.9653966370857}

Counter average: 
Status: {0} `n ---------- `n S-Zabbix
{0}: `n 4
Counter average: @{Name=s-zabbix:hv vp 0; Average=5.86643551294767}
Counter average: @{Name=s-zabbix:hv vp 1; Average=1.59246232101088}
Counter average: @{Name=s-zabbix:hv vp 2; Average=1.06161183102294}
Counter average: @{Name=s-zabbix:hv vp 3; Average=1.16016178713955}

Centos has 2 CPU’s and gives back 0 & 1 which is ok. But after 1 I get

Get-Counter : No data to return.
At line:20 char:18
+ ...      $ret = Get-Counter -Counter $fullcounter -SampleInterval 1 -MaxS ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidResult: (:) [Get-Counter], Exception
    + FullyQualifiedErrorId : CounterApiError,Microsoft.PowerShell.Commands.GetCounterCommand

Same is for zabbix after number 3.

I’m almost there.

2

Answers


  1. Chosen as BEST ANSWER

    Solution:

        $vms = Get-VM | Where { $_.State –eq ‘Running’ }
    
    Foreach ( $vm in $vms ) {
    
       Write-Host 'Status: {0} `n ---------- `n' $vm.Name
    
       $processors = Get-VMProcessor -VMName $vm.Name
    
       Foreach ( $processor in $processors ) {
    
          Write-Host '{0}: `n' $processor.Count
    
          $procCount = $processor.Count 
    
          for($i = 0 ; $i -le $procCount-1; $i++){
    
          $fullcounter = "\" + $env:computername + "Hyper-V Hypervisor Virtual Processor(" + $vm.Name + ":Hv VP " + $i + ")% Guest Run Time"
    
    
              $ret = Get-Counter -Counter $fullcounter -SampleInterval 1 -MaxSamples 30 `
                     | Select-Object -ExpandProperty CounterSamples `
                   | Group-Object -Property InstanceName `
                   | ForEach-Object { 
                      $_ | Select-Object -Property Name, @{n='Average';e= {($_.Group.CookedValue | Measure-Object -Average).Average}};
                    }
             Write-Host "Counter average: $ret"
    
          }
       }
    }
    

    Result:

        Status: {0} `n ---------- `n CenTOS
    {0}: `n 2
    Counter average: @{Name=centos:hv vp 0; Average=13.4647683016234}
    Counter average: @{Name=centos:hv vp 1; Average=13.8969682205744}
    Status: {0} `n ---------- `n S-Zabbix
    {0}: `n 4
    Counter average: @{Name=s-zabbix:hv vp 0; Average=1.26615923294145}
    Counter average: @{Name=s-zabbix:hv vp 1; Average=5.69107385267803}
    Counter average: @{Name=s-zabbix:hv vp 2; Average=1.14422252254857}
    Counter average: @{Name=s-zabbix:hv vp 3; Average=1.44512414780457}
    

  2. If all you’re looking for is the last 30 usage samples from every hypervisor running on your machine, then this code can be drastically simplified. Instead of the C-based logic used in the example, let’s try to script our output based on the data axis of our virtual machines, and work methodically through each. (A more object-oriented approach, fitting of powershell.)

    If you want this data all at the same time, I think it would require some sort of parallel processing, which I’ve never used before. Maybe someone else can tackle that.

    The following script will (supposedly, if the above script works in a similar context) cycle through each hypervisor on your local machine, and then through each processor core, and then print out the counter value (if the counter is configured correctly).

    Needed to use this to get the behavior of the Get-Counter command.

    $vms = Get-VM | Where { $_.State –eq ‘Running’ }
    
    Foreach ( $vm in $vms ) {
       Write-Host 'Status: {0} `n ---------- `n' -f $vm.Name
    
       $processors = Get-VMProcessor -VMName $vm.Name 
    
       Foreach ( $processor in $processors ) {
          Write-Host '{0}: `n' -f $processor.Name #supposedly. Might need to change this
    
          $fullcounter = "\" + $env:computername + "Hyper-V Hypervisor Virtual Processor(" + $vm.Name + ":Hv VP " + $processor.IndexOf($processors) + ")% Guest Run Time"
    
          Foreach ( $i in 1..30 ) {
             $ret = Get-Counter -Counter $fullcounter -SampleInterval 1 -MaxSamples 30 `
                    | Select-Object -ExpandProperty CounterSamples `
                    | Group-Object -Property InstanceName `
                    | ForEach-Object { 
                      $_ | Select-Object -Property Name, @{n='Average';e= {($_.Group.CookedValue | Measure-Object -Average).Average}};
                    }
             Write-Host "Counter average: $ret"
          }
       }
    }
    

    Needs testing.
    This has been optimized for display. If you want your script to return an object, I’d encourage you to use Class HypervisorUnit { } or something.
    If I’ve misunderstood what you’re asking for, let me know.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search