The VMTN PowerCLI Community is a constant source of inspiration for blog posts. User roswellevent raised, in the thread Any way to get virtual machine Nic card usage?, the question if it was possible to get the transmit and receive rate for each vNIC in virtual machines.
Since I’m interested in all things statistics in vSphere I decided to tackle the question. Finding the metrics to use for this kind of report is not too difficult. Under the PerformanceManager Network section we find the metrics net.received.average and net.transmitted.average. And, provided your Statistics Level is set to 3 for the timeframe you want to report on, the metrics capture statistics on the device level.
Great, exactly what we need! A quick check in the Performance tab in the vSphere Client showed an additional problem to solve. The instance didn’t mention Network Adapter 1 but a number.
Background
It turns out that this number is the internal Key used for the vNICs. Could have been a bit more user-friendly in the vSphere Client 🙂
The solution is quite simple, the script fetches all the vNICs of a VM and then stores the Key together with the human-understandable name in a hash table. This hash table allows the script to replace the Instance value by the Name of the vNIC.
The script
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
function Get-VmNicStat{ <# .SYNOPSIS Retrieve network rates per vNIC per VM .DESCRIPTION The function will calculate the average transmit receive rate, over a select time interval, for each vNIC on the VMs selected. .NOTES Author: Luc Dekens .PARAMETER VM The Virtual Machine(s) This is a required parameter. .PARAMETER Start A DateTime value that specifies the start of the timeframe you want to use. This is a required parameter. .PARAMETER Finish A DateTime value that specifies the end of the timeframe you want to use. The default is the current time. .EXAMPLE PS> Get-VM | Get-VmNicStat -Start $start #> param( [CmdletBinding()] [parameter(Mandatory = $true, ValueFromPipeline = $true)] [VMware.VimAutomation.ViCore.Impl.V1.Inventory.VirtualMachineImpl[]]$VM, [parameter(Mandatory = $true)] [System.DateTime]$Start, [System.DateTime]$Finish = (Get-Date) ) begin{ $metrics = "net.received.average","net.transmitted.average" } process{ $stats = Get-Stat -Entity $VM -Stat $metrics -Start $Start foreach($vm in ($stats | Group-Object -Property {$_.Entity.Name})){ $nicTab = @{} $vm.Group[0].Entity.NetworkAdapters | %{ $key = [string]$_.ExtensionData.Key $value = $_.Name $nicTab.Add($key,$value) } $vm.Group | where {$nicTab.ContainsKey($_.Instance)} | Group-Object -Property Instance | %{ New-Object PSObject -Property @{ VM = $vm.Name Start = $Start Finish = $Finish NIC = $nicTab[$_.Group[0].Instance] "Avg Received (KBps)" = [Math]::Round(($_.Group | where {$_.MetricId -eq "net.received.average"} | Measure-Object -Property Value -Average).Average,1) "Avg Transmitted (KBps)" = [Math]::Round(($_.Group | where {$_.MetricId -eq "net.transmitted.average"} | Measure-Object -Property Value -Average).Average,1) } } } } } |
Annotations
Line 33: The metrics the functions uses.
Line 37: Retrieve the statistical data for the virtual machines over the selected timeframe.
Line 39: The function uses the Group-Object cmdlet to split the returned statistical by VM.
Line 40-45: Look at all the vNICs connected to the VM and create a hash table, linking the Key with the Name of the vNIC.
Line 47: The Where-clause will filter out the statistical data for the vNICs of the VM
Line 48: Use the Group-Object to to split the statistical data per vNIC
Line 49-60: Create an object per vNIC per VM
Line 53: Use the hash table to fetch the “Network Adapter x” name of the vNIC
Line 54-59: Calculate the average transmit and recieve values over the selected timeframe.
Sample usage
You can use the function like this
1 2 |
$vms = Get-VM -Name vm* Get-VmNicStat -VM $vms -Start (Get-Date).AddHours(-1) |
And you can also use it in a pipeline, like this
1 2 3 4 |
Get-VM -Name vm* | Get-VmNicStat -Start (Get-Date).AddHours(-1) | Select VM,Start,Finish,NIC,"Avg Received (KBps)","Avg Transmitted (KBps)" | Format-Table -AutoSize |
The resulting output looks like this
Enjoy!