lElOUCHE_79
Enthusiast
Enthusiast

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
LucD
Leadership
Leadership

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
lElOUCHE_79
Enthusiast
Enthusiast

Reply
0 Kudos
LucD
Leadership
Leadership

Correct


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

Reply
0 Kudos
lElOUCHE_79
Enthusiast
Enthusiast

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

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

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

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

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

Name, VMHost, NumCpu, CoresPerSocket, MemoryMB

Reply
0 Kudos
LucD
Leadership
Leadership

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

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

Got It

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

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

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

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

lElOUCHE_79
Enthusiast
Enthusiast

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