VMware Cloud Community
lElOUCHE_79
Enthusiast
Enthusiast
Jump to solution

Get CPU Memory Network Disk Usage

Hello

I'm starting working on new script to Get CPU Memory Network Disk Usage. I'm starting with Average and I will add the Max & Min stats.

My issue is that I'm not able to retreive ESXi name and not able to exclude vCLS from csv report.

 

Below is the script 

 

Get-VM | Where-Object {$_.PowerState -eq "PoweredOn" -notcontains "vCLS"} | Select-Object Name, Host, NumCpu, MemoryMB, `
@{N="CPU Usage (Average), Mhz" ; E={[Math]::Round((($_ | Get-Stat -Stat cpu.usagemhz.average -Start (Get-Date).AddDays(-30) -IntervalMins 5 
    | Measure-Object Value -Average).Average),2)}}, `
@{N="Memory Usage (Average), %" ; E={[Math]::Round((($_ | Get-Stat -Stat mem.usage.average -Start (Get-Date).AddDays(-30) -IntervalMins 5 
    | Measure-Object Value -Average).Average),2)}} , `
@{N="Network Usage (Average), KBps" ; E={[Math]::Round((($_ | Get-Stat -Stat net.usage.average -Start (Get-Date).AddDays(-30) -IntervalMins 5 
    | Measure-Object Value -Average).Average),2)}} , `
@{N="Disk Usage (Average), KBps" ; E={[Math]::Round((($_ | Get-Stat -Stat disk.usage.average -Start (Get-Date).AddDays(-30) -IntervalMins 5 
    | Measure-Object Value -Average).Average),2)}} |`
Export-Csv -Path .\AverageUsage.csv
Reply
0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

Try with

 

VMHost = $_.Group[0].Entity.VMHost.Name.Split('.')[0]

 

Since the Value of cpu.ready.summation is in milliseconds, you have to divide by 1000.

 

            'CPUReadyS milliseconde' = [Math]:Round((($_.Group | Where-Object{$_.MetricId -eq 'cpu.ready.summation'}).Value/1000),1)

 


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

View solution in original post

15 Replies
LucD
Leadership
Leadership
Jump to solution

Try like this.

Btw, calling Get-Stat that many times is rather inefficient. Try to use 1 Get-Stat call and then Group-Object to split the results per VM.
There are multiple examples of this concept in this community.

Get-VM | Where-Object {$_.PowerState -eq "PoweredOn" -and $_.Name -notmatch "vCLS"} | 
Select-Object Name, 
@{N='Host';E={$_.VMHost.Name}},
NumCpu, MemoryMB,
@{N="CPU Usage (Average), Mhz" ; E={[Math]::Round((($_ | Get-Stat -Stat cpu.usagemhz.average -Start (Get-Date).AddDays(-30) -IntervalMins 5 | Measure-Object Value -Average).Average),2)}},
@{N="Memory Usage (Average), %" ; E={[Math]::Round((($_ | Get-Stat -Stat mem.usage.average -Start (Get-Date).AddDays(-30) -IntervalMins 5 | Measure-Object Value -Average).Average),2)}} ,
@{N="Network Usage (Average), KBps" ; E={[Math]::Round((($_ | Get-Stat -Stat net.usage.average -Start (Get-Date).AddDays(-30) -IntervalMins 5 | Measure-Object Value -Average).Average),2)}} ,
@{N="Disk Usage (Average), KBps" ; E={[Math]::Round((($_ | Get-Stat -Stat disk.usage.average -Start (Get-Date).AddDays(-30) -IntervalMins 5 | Measure-Object Value -Average).Average),2)}} |
Export-Csv -Path .\AverageUsage.csv




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

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Correct


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

Reply
0 Kudos
lElOUCHE_79
Enthusiast
Enthusiast
Jump to solution

I made it like this I'm getting error.
without "| Select-Object Name, VMHost, NumCpu, CoresPerSocket, MemoryMB," no error



$sStat = @{
    Stat = 'cpu.usage.average','mem.usage.average','net.usage.average','disk.usage.average'
    Start = (Get-Date).AddDays(-30)
    Instance = ''
    MaxSamples = [int]::MaxValue
    Entity = Get-VM | Where-Object {$_.PowerState -eq "PoweredOn" -and $_.Name -notmatch "vCLS"} | Select-Object Name, VMHost, NumCpu, CoresPerSocket, MemoryMB,`
    ErrorAction = 'SilentlyContinue'
}
Get-Stat @SStat |
Group-Object -Property {$_.Entity.Name} |
ForEach-Object -Process {$_.Group | Group-Object -Property Timestamp |
    ForEach-Object -Process {
        New-Object -TypeName PSObject -Property ([ordered]@{
            VM = $_.Group[0].Entity.Name
            Timestamp = $_.Group[0].Timestamp
            CpuAvg = ($_.Group | Where-Object{$_.MetricId -eq 'cpu.usage.average'}).Value
            MemAvg = ($_.Group | Where-Object{$_.MetricId -eq 'mem.usage.average'}).Value
            DiskAvg = ($_.Group | Where-Object{$_.MetricId -eq 'disk.usage.average'}).Value
            NetAvg = ($_.Group | Where-Object{$_.MetricId -eq 'net.usage.average'}).Value
        })
    }
} | Export-Csv -Path .\report.csv -NoTypeInformation -UseCulture

 

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

The Select-Object is not needed, just use the Get-VM and the Where-clause.


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

Reply
0 Kudos
lElOUCHE_79
Enthusiast
Enthusiast
Jump to solution

honestly didn't get you :slightly_smiling_face: 

you mean something like this?

Entity = Get-VM | Where-Object {$_.PowerState -eq "PoweredOn" -and $_.Name -notmatch "vCLS"} Name, VMHost, NumCpu, CoresPerSocket, MemoryMB
Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

No, like this

$sStat = @{
    Stat = 'cpu.usage.average','mem.usage.average','net.usage.average','disk.usage.average'
    Start = (Get-Date).AddDays(-30)
    Instance = ''
    MaxSamples = [int]::MaxValue
    Entity = Get-VM | Where-Object {$_.PowerState -eq "PoweredOn" -and $_.Name -notmatch "vCLS"} 
    ErrorAction = 'SilentlyContinue'
}


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

lElOUCHE_79
Enthusiast
Enthusiast
Jump to solution

it didn't collect the below details in the csv report

Name, VMHost, NumCpu, CoresPerSocket, MemoryMB

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

You have to add those to the New-Object hash table, use the Expression part of the Select-Objact calculated properties.


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

lElOUCHE_79
Enthusiast
Enthusiast
Jump to solution

totaly lost :grinning_face_with_smiling_eyes: 

I beleive that I should add what I need in :

 

        New-Object -TypeName PSObject -Property ([ordered]@{
            VM = $_.Group[0].Entity.Name
            Timestamp = $_.Group[0].Timestamp
            Name = $Entity.Name
            'CpuAvg %' = ($_.Group | Where-Object{$_.MetricId -eq 'cpu.usage.average'}).Value
            'CPUReadyS milliseconde' = ($_.Group | Where-Object{$_.MetricId -eq 'cpu.ready.summation'}).Value
            'MemAvg %' = ($_.Group | Where-Object{$_.MetricId -eq 'mem.usage.average'}).Value
 
Right?
Reply
0 Kudos
lElOUCHE_79
Enthusiast
Enthusiast
Jump to solution

Got It

VMHost = $_.Group[0].Entity.VMHost
Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

EVen better would be

VMHost = $_.Group[0].Entity.VMHost.Name

That way you don't rely on the automatic conversion from a VMHost object to a String


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

lElOUCHE_79
Enthusiast
Enthusiast
Jump to solution

Thanks @LucD it's working.

I made it like this :

$sStat = @{
    Stat = 'cpu.usage.average','cpu.ready.summation','mem.usage.average','net.usage.average'
    Start = (Get-Date).AddDays(-30)
    Instance = ''
    MaxSamples = [int]::MaxValue
    Entity = Get-VM | Where-Object {$_.PowerState -eq "PoweredOn" -and $_.Name -notmatch "vCLS"}
    ErrorAction = 'SilentlyContinue'
}
Get-Stat @sStat |
Group-Object -Property {$_.Entity.Name} |
ForEach-Object -Process {$_.Group | Group-Object -Property Timestamp |
    ForEach-Object -Process {
        New-Object -TypeName PSObject -Property ([ordered]@{
            VM = $_.Group[0].Entity.Name
            Timestamp = $_.Group[0].Timestamp
            VMHost = $_.Group[0].Entity.VMHost.Name
            NumCpu = $_.Group[0].Entity.NumCPU
            CoresPerSocket = $_.Group[0].Entity.CoresPerSocket
            MemoryMB = $_.Group[0].Entity.MemoryMB
            'CpuAvg %' = ($_.Group | Where-Object{$_.MetricId -eq 'cpu.usage.average'}).Value
            'CPUReadyS milliseconde' = ($_.Group | Where-Object{$_.MetricId -eq 'cpu.ready.summation'}).Value
            'MemAvg %' = ($_.Group | Where-Object{$_.MetricId -eq 'mem.usage.average'}).Value
            'NetAvg KBps' = ($_.Group | Where-Object{$_.MetricId -eq 'net.usage.average'}).Value
        })
    }
} | Export-Csv -Path .\report.csv -NoTypeInformation -UseCulture

 

A quick question, do you have any idea to get the VMHost without FQDN?

Also I'm not able to find the best way to show  'cpu.ready.summation' in secondes

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Try with

 

VMHost = $_.Group[0].Entity.VMHost.Name.Split('.')[0]

 

Since the Value of cpu.ready.summation is in milliseconds, you have to divide by 1000.

 

            'CPUReadyS milliseconde' = [Math]:Round((($_.Group | Where-Object{$_.MetricId -eq 'cpu.ready.summation'}).Value/1000),1)

 


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

lElOUCHE_79
Enthusiast
Enthusiast
Jump to solution

Thank you @LucD it's working fine

regarding there's a Typo issue in Math :slightly_smiling_face: 

'CPUReadyS milliseconde' = [Math}:Round((($_.Group | Where-Object{$_.MetricId -eq 'cpu.ready.summation'}).Value/1000),1)

 

'CPUReadyS Secondes' = [Math]::Round((($_.Group | Where-Object {$_.MetricId -eq 'cpu.ready.summation'}).Value/1000),1)

 

Many thanks 

 

Reply
0 Kudos