Hi Luc,
just checking yur post
vNIC transmit and receive rates - LucD notes
i have been trying to find this for two vms and three esxi hosts and stuck in following questions.
1:code does not work as get follwoing error .
C:\users\user1\desktop\> Get-VmNicStat
cmdlet Get-VmNicStat at command pipeline position 1
Supply values for the following parameters:
VM[0]: vm1
VM[1]: vm2
VM[2]:
Start: $start
Cannot recognize "$start" as a System.DateTime due to a format error.
Start: Thursday, October 04, 2018 9:18:02 PM
Get-VmNicStat : Cannot process argument transformation on parameter 'VM'. Cannot convert value
"System.Collections.ArrayList" to type "VMware.VimAutomation.ViCore.Impl.V1.Inventory.VirtualMachineImpl[]". Error:
"Cannot convert the "vm1" value of type "System.String" to type
"VMware.VimAutomation.ViCore.Impl.V1.Inventory.VirtualMachineImpl"."
At line:1 char:1
+ Get-VmNicStat
+ ~~~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Get-VmNicStat], ParameterBindingArgumentTransformationException
+ FullyQualifiedErrorId : ParameterArgumentTransformationError,Get-VmNicStat
also how do we know if these valsue is high as there are some alerts like below
vm1 tx rate is high 10554 KBps
esxi 1 rx rate is high 30968 KBps
vm2 transmit rate is high (13941 KBps
esxi 3 transmit rate is high (41013 KBps)
esxi 4 receive rate is high (30515 KBps)
is there any threshold mentioned somewhere ??
That is an old post, and some things have changed, more specifically the types for PowerCLI.
See PowerCLI Best Practice: Correct Use of Strong Typing
Another change is the removal of the NetworkAdapters property on the VM object.
Try this updated version.
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.Types.V1.Inventory.VirtualMachine[]]$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($vmInstance in ($stats | Group-Object -Property {$_.Entity.Name})){
$nicTab = @{}
Get-NetworkAdapter -VM $vmInstance.Group[0].Entity | %{
$key = [string]$_.ExtensionData.Key
$value = $_.Name
$nicTab.Add($key,$value)
}
$vmInstance.Group | where {$nicTab.ContainsKey($_.Instance)} |
Group-Object -Property Instance | %{
New-Object PSObject -Property @{
VM = $vmInstance.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)
}
}
}
}
}
$vms = Get-VM -Name MyVM
Get-VmNicStat -VM $vms -Start (Get-Date).AddHours(-1)
The alarms that are fired contain the thresholds.
Where do see these alerts?
Can you include a screenshot?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
That is an old post, and some things have changed, more specifically the types for PowerCLI.
See PowerCLI Best Practice: Correct Use of Strong Typing
Another change is the removal of the NetworkAdapters property on the VM object.
Try this updated version.
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.Types.V1.Inventory.VirtualMachine[]]$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($vmInstance in ($stats | Group-Object -Property {$_.Entity.Name})){
$nicTab = @{}
Get-NetworkAdapter -VM $vmInstance.Group[0].Entity | %{
$key = [string]$_.ExtensionData.Key
$value = $_.Name
$nicTab.Add($key,$value)
}
$vmInstance.Group | where {$nicTab.ContainsKey($_.Instance)} |
Group-Object -Property Instance | %{
New-Object PSObject -Property @{
VM = $vmInstance.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)
}
}
}
}
}
$vms = Get-VM -Name MyVM
Get-VmNicStat -VM $vms -Start (Get-Date).AddHours(-1)
The alarms that are fired contain the thresholds.
Where do see these alerts?
Can you include a screenshot?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
well i got same error again related to conversion of string to the type meantioned in param block.
so i changed to following (orange line) hope it make sense as this used to work for other simple function.
param(
[CmdletBinding()]
[parameter(Mandatory = $true, ValueFromPipeline = $true)]
[string[]]$VM,
[parameter(Mandatory = $true)]
[System.DateTime]$Start,
[System.DateTime]$Finish = (Get-Date)
)
iam checking thresholds also .
That will not work.
Can you attach the script you are running?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
its giving a new error now .
AM Get-Stat The metric counter "net.received.average" doesn't exist
for entity "vm1". same for "net.transmitted.average"
script which iam running is what yu sent in last post with modifications in param block .
function Get-VmNicStat-upd{
<#
.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)]
[string[]]$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($vmInstance in ($stats | Group-Object -Property {$_.Entity.Name})){
$nicTab = @{}
Get-NetworkAdapter -VM $vmInstance.Group[0].Entity | %{
$key = [string]$_.ExtensionData.Key
$value = $_.Name
$nicTab.Add($key,$value)
}
$vmInstance.Group | where {$nicTab.ContainsKey($_.Instance)} |
Group-Object -Property Instance | %{
New-Object PSObject -Property @{
VM = $vmInstance.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)
}
}
}
}
}
Get-Stat : 10/5/2018 2:58:50 AM Get-Stat The metric counter "net.received.average" doesn't exist
for entity "MOPESICA07".
At C:\users\in0079d6\desktop\Technicolor_script\rx-tx rate.ps1:81 char:18
+ $stats = Get-Stat -Entity $VM -Stat $metrics -Start $Start
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ResourceUnavailable: (net.received.average:String) [Get-Stat], VimExc
eption
+ FullyQualifiedErrorId : Client20_RuntimeDataServiceImpl_CheckUserMetrics_MetricDoesntExist,VM
ware.VimAutomation.ViCore.Cmdlets.Commands.GetViStats
Get-Stat : 10/5/2018 2:58:50 AM Get-Stat The metric counter "net.transmitted.average" doesn't
exist for entity "MOPESICA07".
At C:\users\in0079d6\desktop\Technicolor_script\rx-tx rate.ps1:81 char:18
+ $stats = Get-Stat -Entity $VM -Stat $metrics -Start $Start
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ResourceUnavailable: (net.transmitted.average:String) [Get-Stat], Vim
Exception
+ FullyQualifiedErrorId : Client20_RuntimeDataServiceImpl_CheckUserMetrics_MetricDoesntExist,VM
ware.VimAutomation.ViCore.Cmdlets.Commands.GetViStats
That's because you are not collecting those metrics.
These metrics need statistics level 3 to be able to get the values per vNic.
You didn't show what you used as a Start value, but if you keep that below 1 hour, it should retrieve the metrics from Realtime.
And there all metrics are captured.
On the [string] parameter, you didn't include how you call the function.
PS: you can also attach a file, no need to dump it in the thread.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
i am putting time less than i hour as in orange.
(get-date).AddMinutes(-30)
Friday, October 05, 2018 3:19:37 AM
iam not sure how to enable stats level 3 .
Can you try changing the Get-Stat line as follows
$stats = Get-Stat -Entity $VM -Stat $metrics -Start $Start -Realtime
You can change the Statistics Level via the Web Client (VCSA - Configure tab - General - Edit - Statistics).
Or you can use a script.
Something like this
$si = Get-View ServiceInstance
$perfMgr = Get-View -Id $si.Content.PerfManager
$int = $perfMgr.HistoricalInterval | where{$_.Name -eq 'Past day'}
$int.Level = 3
$perfMgr.UpdatePerfInterval($int)
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
TX i am checking this but I could not undestand the following
On the [string] parameter, you didn't include how you call the function
I m not getting that conversion error so any thing else needs to be added in param block
What I meant to say, do you call the function with the Name of a VM (then a [string] will work) or with a VirtualMachine object (output of a Get-VM cmdlet).
In the latter case [string] will not work.
The function was created with the idea that you pass a VirtualMachine object.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
I’m going run one more time and will attach output.
however I call function and enter ,it prompted me to enter vm1 and then enter again to enter vm2.
Can't you call the function as I showed in my first reply?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Thnaks it worked as per yur first reply .i did not change statistics level to 3 .
however it worked for last i hour.
i tried to modify to run for esxi hosts also .could you please check as its not working .
one thing i am finding is when i run get-module command in powershell i dont find following
VMware.VimAutomation.ViCore.Types.V1.Inventory.vmhost and
VMware.VimAutomation.ViCore.Types.V1.Inventory.virtualmachine
When a module is not yet loaded into your PS session, it will not show up with a Get-Module.
To see all modules, you need to do
Get-Module -ListAvailable
When you want to report on ESXi vnic stats, the script needs to be changed.
Something like this
function Get-esxiNicStat{
<#
.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.Types.V1.Inventory.vmhost[]]$esxi,
[parameter(Mandatory = $true)]
[System.DateTime]$Start,
[System.DateTime]$Finish = (Get-Date)
)
begin{
$metrics = "net.received.average","net.transmitted.average"
}
process{
$stats = Get-Stat -Entity $esxi -Stat $metrics -Start $Start -Realtime
foreach($esxInstance in ($stats | Group-Object -Property {$_.Entity.Name})){
$esxInstance.Group |
Group-Object -Property Instance | %{
New-Object PSObject -Property @{
esxi = $esxInstance.Name
Start = $Start
Finish = $Finish
NIC = $_.Name
"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)
}
}
}
}
}
$esxi = Get-VMHost -Location Cluster1
Get-esxiNicStat -esxi $esxi -Start (Get-Date).AddHours(-1)
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Thanks Luc .it worked fine .
hi luc ,
i am getting some numbers when i run this script .we need to set some threshold above which it should alert .
will that threshold depends on speed of physical nics.
may be 80 percent bandwidth of physical nic.
sorry this not powercli question but thought if you are aware of it.
The speed of the pNICs is one criterium, so yes, you can create an alarm that fires when a specific threshold is exceeded.
But there might be other factors you should take into account
Are the vNICs used in a VSS or a VDS?
Are multiple vNICs teamed for a switch?
Are multiple types of traffic (VM, management, vMotion...) passing over the same vNICs?
And as always, measuring is knowing!
Since each environment is different, you will need to measure for a period of time, while your typical workloads are running, to determine what are realistic thresholds for your environment.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Thanks i am going to check this.
appreciate your help.
i am trying to change stats level to 3 get more past data to analyses but will it cause any impact in terms of DB size .
di i need to change the size of DB or any other things before changing stats to level 3 ..