VMware Cloud Community
nikpetrov95
Contributor
Contributor
Jump to solution

Create a custom CPU alarm for VM using PowerCli

Hello! I need to create an alarm on the CPU for each virtual machine, after the alarm has worked, I need to send a message to the user's mail, mail information should be taken from the user attribute of VM (I did it myself). Please help me with this matter.

Tags (1)
43 Replies
nikpetrov95
Contributor
Contributor
Jump to solution

No, I want to make changes to the current script.

$ErrorActionPreference= 'Stop'

$metricName = 'cpu.usage.average'

$mGroup,$mName,$mRollup = $metricName.Split('.')

$si = Get-View ServiceInstance

$perfMgr = Get-View -Id $si.Content.PerfManager

$metric = $perfMgr.PerfCounter |

    where{$_.GroupInfo.Key -eq $mGroup -and

          $_.NameInfo.Key -eq $mName -and

          $_.RollupType -eq $mRollup}

$VMcluster=read-host "Enter Cluster name"

$VM_with_contact=(Get-Cluster $VMcluster|get-vm |Get-Annotation -CustomAttribute 'Contact'|where{$_.Value -ne ""}).AnnotatedEntity.name

Get-VM $VM_with_contact|?{$_.Name -notlike  "*Template*" -and $_.Name -notlike  "*Old*"} -PipelineVariable vm |

ForEach-Object -Process {

    $userEmail = (Get-Annotation -Entity $vm -CustomAttribute 'Contact').value -replace " "

    $sAlarmTrigger = @{

        Metric              = Get-Metric -MetricGroup 'CPU' -Name 'usage' | where{$_.Key -eq $metric.Key}

        MetricAlarmOperator = 'Above'

        Red                 = 9500

        RedIntervalSeconds  = 86400

        EntityType          = 'VirtualMachine'

    }

    $trigger = New-AlarmTrigger @sAlarmTrigger

    $sAlarmAction = @{

        Email   = $true

Body = "$vm CPU Usage is above 95% for 24 hours , please check your OS."

        Subject = "High CPU Usage $vm"

        To      = @($userEmail.Split(';'))

    }

    $action = New-AlarmAction @sAlarmAction

    $sAlarmDef = @{

        Name         = "CPU High $vm"

        Description  = 'Trigger alarm when CPU utilisation is too high'

        Entity       = $vm

        AlarmTrigger = $trigger

        AlarmAction  = $action

    }

    New-AlarmDefinition @sAlarmDef|ft -AutoSize

}

$ErrorActionPreference= 'Continue'

And after running the script, I want to see the following:

Get-AlarmDefinition -Name "CPU High DBA340"| Get-AlarmAction |Get-AlarmActionTrigger

StartStatus     EndStatus       Repeat

-----------     ---------       ------

Yellow          Red             TRUE

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Ok, try like this

$vmNames = 'test01','test02'

$metricName = 'cpu.usage.average'


$mGroup,$mName,$mRollup = $metricName.Split('.')

$si = Get-View ServiceInstance

$perfMgr = Get-View -Id $si.Content.PerfManager

$metric = $perfMgr.PerfCounter |

    where{$_.GroupInfo.Key -eq $mGroup -and

          $_.NameInfo.Key -eq $mName -and

          $_.RollupType -eq $mRollup}


Get-VM -Name $vmNames -PipelineVariable vm |

ForEach-Object -Process {

    Get-AlarmDefinition -Name 'CPU High' -Entity $_ -ErrorAction SilentlyContinue |

    Remove-AlarmDefinition -Confirm:$false

    $userEmail = (Get-Annotation -Entity $vm -CustomAttribute 'Contact').value


    $sAlarmTrigger = @{

        Metric              = Get-Metric -MetricGroup 'CPU' -Name 'usage' | where{$_.Key -eq $metric.Key}

        MetricAlarmOperator = 'Above'

        Red                 = 7500

        RedIntervalSeconds  = 300

        EntityType          = 'VirtualMachine'

    }

    $trigger = New-AlarmTrigger @sAlarmTrigger


    $sActionTrigger = @{

        StartStatus = 'yellow'

        EndStatus = 'red'

        Repeat = $true

    }

    $actionTrigger = New-AlarmActionTrigger @sActionTrigger


    $sAlarmAction = @{

        Email   = $true

        Subject = 'CPU Usage high'

        To      = $userEmail

        AlarmActionTrigger = $actionTrigger

    }

    $action = New-AlarmAction @sAlarmAction


    $sAlarmDef = @{

        Name         = 'CPU High'

        Description  = 'Trigger alarm when CPU utilisation is too high'

        Entity       = $vm

        AlarmTrigger = $trigger

        AlarmAction  = $action

        ActionRepeatMinutes = 5

    }


    New-AlarmDefinition @sAlarmDef

}


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

0 Kudos
nikpetrov95
Contributor
Contributor
Jump to solution

LucD​, Thank you so much!

0 Kudos
mk5213
Contributor
Contributor
Jump to solution

Hi, I am a bit confused on the creation of alarms in vcenters. I have seen CreateAlarm used but only a long time ago, is that deprecated and New-AlarmDefinition the new way of creating alarms in PowerCLI? Sorry if I am a bit misinformed on the topic. Any input is greatly appreciated, Thanks!

0 Kudos
LucD
Leadership
Leadership
Jump to solution

You are corrected, there are a number of new cmdlets for Alarms.

See

Get-Command -Name *Alarm*

Some features of Alarms can not be created by these cmdlets, for those you will still need the API.


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

0 Kudos
mk5213
Contributor
Contributor
Jump to solution

Thank you LucD, that clears it up. Right now I am just creating alarms at the datacenter level, but is there a way to create alarms for the entire vcenter? I read this here but I am a bit confused if I can make alarms for the entire vcenter?

0 Kudos
mk5213
Contributor
Contributor
Jump to solution

pastedImage_0.png

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Use the Folder named Datacenters


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

mk5213
Contributor
Contributor
Jump to solution

Thank you that worked, is it possible to use for example a json or csv to initialize alarms in PowerCLI?

0 Kudos
LucD
Leadership
Leadership
Jump to solution

No, not directly.

You can store the variable data (AlarmName, Description...) in an external file.

But you would still need a script to define the Alarms (using the data from the external file).


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

0 Kudos
mk5213
Contributor
Contributor
Jump to solution

Hey LucD, I am trying to get the input for alarms working with json files. I have a json file that gets taken in and successfully have everything stored in a hashtable of hashtables, but I cant get the cmdlet to work with it for some reason:

$actionTrigger = New-AlarmActionTrigger $json.sActionTrigger

This is the error message for this line, as well as the contents of $json.sActionTrigger:

pastedImage_0.png

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Did you already try casting your value from the JSON file to ManagedEntityStatus type

[VMware.Vim.ManagedEntityStatus]$json.sActionTrigger.Value


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

0 Kudos
mk5213
Contributor
Contributor
Jump to solution

Just tried the following:

$actionTrigger = New-AlarmActionTrigger [VMware.Vim.ManagedEntityStatus]$json.sActionTrigger.Value

and got the following output:

pastedImage_0.png

0 Kudos
LucD
Leadership
Leadership
Jump to solution

What exactly do you have in $json.sActionTrigger.Value?

Or else share part of the JSON file.


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

0 Kudos
mk5213
Contributor
Contributor
Jump to solution

Now that you say that just checked what is stored in $json.sActionTrigger.Value and nothing comes up. But if I do run $json.sActionTrigger it shows the correct name value pairs like in my above picture, I am confused why this is.

0 Kudos
mk5213
Contributor
Contributor
Jump to solution

The only thing I have stored in the JSON is the hashtable sActionTrigger:

pastedImage_0.png

0 Kudos
LucD
Leadership
Leadership
Jump to solution

How did you create that JSON file?
That field should contain green,yellow or red


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

0 Kudos
mk5213
Contributor
Contributor
Jump to solution

pastedImage_0.png

Yeah so I actually got this to work without nested objects in the json file. So before I just had the json only contain the startstatus, endstatus and repeat and it worked perfectly. But I am trying to contain all the hastables in one json file, so i am testing right now with just doing one hastable in the hashtable but I am hoping to add them for all the other hastables in the script. I just don't understand why the cmdlet works with a hastable, but I cant get it to work with a hashtable within a hastable. It may not be possible but I was just trying to see if you would possibly know what is wrong

0 Kudos
LucD
Leadership
Leadership
Jump to solution

I would need to see the relevant part of your code and a sample JSON extract to further analyse.


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

0 Kudos
mk5213
Contributor
Contributor
Jump to solution

Ok if need be I can do that but I think I have an idea of what the issue is. I basically have a hash table variable I am trying to splat with. I didn't assign it  in the script like you created your splatting variable in your example, I have a function create a hashtable from a json file. I read somewhere that you cannot splat with a created hashtable, do you think this is the issue? It is treating my hashtable as the first parameter instead of using the name-value pairs in the hashtable

0 Kudos