Alarm actions – enable – disable – report

Another post triggered by a question in the VMTN PowerCLI community. The user wanted to know how he could create a report that showed for which vSphere entities the alarm actions were disabled.

To set the stage, a short overview of what this is all about. In vSphere you can, since vSphere 4, disable and enable alarm actions for all the managed entities. This option is available from the vSphere client

alarm-action-old-client

and from the vSphere Web client.

alarm-action-web-client

But how to automate these actions, and more importantly in this case, how to report on the active settings ? Like always PowerCLI to the rescue.

The script

Annotations

Line 23: We declare the Entity parameter as a base Inventory  object. That way you can pass all types of vSphere entities to the function.

Line 33-39,71-77: In the $objects variable the function collects all the entities involved. In case Recurse is True, all the child entities are obtained through the Get-Inventory cmdlet.

Line 41: The function calls the EnableAlarmActions method to change the alarm actions state of each entity. The value of the Enabled switch determines if the alarm actions will be enabled or disabled.

Line 70: This line makes sure we have the latest situation for the entity. Remember that the objects PowerCLI produces are not updated automatically when something changes in the entity.

Line 81: To make the Type property a bit more readable, the Impl and Wrapper suffixes are removed.

Sample usage

The Get-AlarmActionState function is quite easy to use. In the first example we will ask for the state of the alarms on a cluster

The result is displayed on the console as follows.

alarm-action-report-2

The function can also be used in a pipeline construct. The following lines will do exactly the same as the previous example.

To change the state of the alarm actions, we can use the Set-AlarmActionState function. The following example will disable the alarm actions on Cluster1 and all its children. To confirm the change, the samepl calls the Get-AlarmActionState function to display the state.

In the console output we can see that the state of the alarm actions has effectively been changed. And this for the cluster and all its child entities.

alarm-action-report

Another vSphere feature we can now use in our automation scripts.
Enjoy !

40 Comments

    RA

    Hello Luc,
    I need to disable alarms at the vCenter level, anyway of doing this (it can be PowerCLI, API, all is fine).
    I normally use something like this (which is based on your original script), but vCenter does not have a MoRef (or I don’t know how to get it).

    $esx_host = Get-VMHost -Name $esxi_hostname

    $alarmMgr = Get-View AlarmManager
    ForEach ($hosts in $esx_host) {$alarmMgr.EnableAlarmActions($hosts.Extensiondata.MoRef,$true)}

    Any help is much appreciated, thank you!

      LucD

      You can find the vCenters root, and it’s MoRef, with

      Get-Folder -Name Datacenters

      Then you could do

      $alarmMgr = Get-View AlarmManager
      $root = Get-Folder -Name Datacenters
      $alarmMgr.EnableAlarmActions($root.ExtensionData.MoRef, $true)

        RA

        Wow Luc…I’ve spent the best part of today trying to find how to do this, thank you so much!

        I’m going to abuse your kindness and ask you if you have any clue on the URI required to do this through API (reason is that this is an Ansible project and I’m trying to limit using PowerCLI as much as possible due to time taken for login).

        Thank you again!

          LucD

          Afaik, the methods available through the AlarmManager are not available through any REST API (yet).

          You could call the method via the MOB using the Invoke-WebRequest cmdlet.
          But that is definitely not done through a simple URI, it will be again a script.
          You will have to authenticate and pass the correct parameters in the Body.

            RA

            Thanks for the tip Luc, I’ll def look into that since I can use Ansible URI module to do that.

    AlChard

    Hello Luc,

    Good Day.

    Newbie here on PowerShell/PowerCLI and in general in scrpting. I’ve tried to use this:

    $cluster = Get-Cluster MyClusterName
    Get-AlarmActionState -Entity $cluster -Recurse:$false

    Apparently, it seemed when I tried to type in or look for Get-AlarmActionState there is none so that script doesn’t worked – it says is not recognized as the name of the cmdlet, function. 🙁

    I hope this message will reach you and you can help me out.

    Thank you in advance.

      LucD

      Hi,
      You have to make the functions “known” to PowerShell.
      You can do that by dot-sourcing the .ps1 file into which you copy the functions.

      – copy the code to a .ps1 file, for example AlarmActionState.ps1
      – dot-source that .ps1 file. Note that space between the 2 dots

      . .\AlarmActionState.ps1

      Now you can call Get-AlarmActionState and Set-AlarmActionState

        AlChard

        I’ve save that exact same parameter to a txt file then renamed to .ps1 file on my desktop and open powershell cmd then go to my desktop directory and key in this:

        . .\AlarmActionState.ps1 (with a space on the middle of both dots)

        But another error comes out that Get-Cluster is not recognize as the name of a cmdlet then another error on the Get-AlarmActionState same error as the first time it runs.

          LucD

          Did you save the code for both functions from the blog post to that .ps1 file?
          I mean the code you find under The Script section in the blog post.

          If Get-Cluster is not recognised that could mean that
          – PowerCLI is not installed
          – that the $env:PSModulePath doesn’t include the folder where you installed PowerCLI.

            AlChard

            It looks like I understood it already however it now’s throws the error:

            Unable to find type Unable to find type [VMware.VimAutomation.ViCore.Impl.V1.Inventory.InventoryItemImpl]

            ps1:65 char:5

              LucD

              It looks like your PowerCLI installation might have issues.
              I would suggest removing and reinstalling PowerCLI

                AlChard

                Thanks Luc, I was able to execute the below parameter in PowerCLI with no issue:

                $cluster = Get-Cluster Cluster1
                Get-AlarmActionState -Entity $cluster -Recurse:$false

                However, when I changed the recurse value to true it throws this error below, I got a result for Resource Pool, Cluster and VMHost but there where 2 VMs that are not included or missing (one is powered on and the other is powered off):

                Get-Inventory exception has been thrown by the target of an invocation
                ps1:73 char:19

                Any idea what went wrong?

        Srinivas

        Hi LucD

        we have the following challenge on the vCenter payload / snmp message:

        VCenter is configured with an alert name, and separate from that, with a Description. However, when the SNMP message goes out, “the system” is combining the alert name together with the Description in a single string. For example:
        The settings are:
        • Alert Name: Infra_*
        • Description: datastore at 85% utilization.
        But the SNMP message has
        * Infra_* datastore at 85% utilization.

        The problem is that since the percentage is a variable, if the ticket is not yet close and another alerts goes out at 90%, then monitoring tool will think it is a different incident and create a new ticket.
        Therefore, we want is for vCenter to keep the Alert name and the description separate from each other. Can this be achieved in script? if so can you please help on this.

          LucD

          I’m afraid that is a vCenter internal, and hence can’t be changed.
          You could split the SNMP message on arrival at the SNMP Manager and only keep the Name part.

            Srinivas

            Thanks a lot for your response, much appreciated your service.

            Is there anything we can do scripting to split if we opt for send alerts in mail.

              LucD

              You can use a number of variables in the Subject and Body of the emails.
              Just use curly braces with the action name.

              {alarmName} with event {eventDescription}

              Note that the action list values are rather limited

                Srinivas

                Luc, can you help with some scripts if you already have or can you please share some reference links for scripts.

                  LucD

                  William has an example in Customizing vCenter Alarm Email Subject and Body

                    Srinivas

                    Thanks a lot Luc again.

    Som

    Is there a way to disable a single alarm for a specific object?

    Ex: Disable only 1 specific alarm for a specific VM, where the alarm is defined at the vCenter Level and cannot be disabled on the VM itself?

      LucD

      Hi,
      I’m afraid that is not possible.
      Luc

        Som

        Thank you for the update brother.
        I can finally stop searching for a way to get this done now.

    David Griswold

    Sorry to necro an old post, but 1) is this code still valid? and 2) has it been replaced by any newer PowerCLI cmdlets?

      LucD

      Hi David,
      Yes, that code is still valid (just tried it in a vSphere7 environment).

      Although there have been a number of Alarm related cmdlets since this post was published, afaik none of those offers to possibility to check if Alarm actions are enabled for a specific entity.

    Jeff NOTEBAERT

    Luc

    I forgot to ask, do there is a way to track who disable the alarm of a device (owner) ?

    Thanks

    Jeff NOTEBAERT

    Luc

    Thanks for this nice function. I’m trying to use it in my environment to generate a report of all disable devices (cluster, VM host, VM, …)

    Do you know why this filter doesn’t work ?

    Get-AlarmActionState -Entity $cluster -Recurse:$true | where {$_.Alarm_actions_enabled -eq “False”} # | Select Name, type

    Thanks

      LucD

      Hi Jeff,
      The property you want to use in the Where-clause has some blanks in it, so you’ll have to place the propertyname between quotes. Like this

      where {$_."Alarm actions enabled" -eq "False"}

      You can do auditing of changes to an alarm definition by tracking the AlarmReconfiguredEvent entries in the events DB.
      Let me know if you need some help with such a script ?

        Satish

        LucD,

        I need to be notified whenever an VCenter alarm is enabled or disabled along with person’s name who performed the action.

        Can you suggest if any script for this?

        Regards,
        Satish

          LucD

          Hi Satish,
          I would look at the AlarmReconfiguredEvent events, if someone changes enabled/disabled, it should be in these events.

        Dimple

        Hi Lucd,

        I do have the requirement to find who and when the alarm was disabled on an entity like cluster. Can you help me with it please.

        Thanks
        Dimple

    Ravi

    having issue, some one cleared the vcenter hardware alarm , how to collect host having hardware issue, is there any powercli script ?

      LucD

      Hi Ravi,
      Sorry for not replying sooner.
      With my Get-VIEventPlus function you can do something like this

      function Get-VIEventPlus {
      <# .SYNOPSIS Returns vSphere events .DESCRIPTION The function will return vSphere events. With the available parameters, the execution time can be improved, compered to the original Get-VIEvent cmdlet. .NOTES Author: Luc Dekens .PARAMETER Entity When specified the function returns events for the specific vSphere entity. By default events for all vSphere entities are returned. .PARAMETER EventType This parameter limits the returned events to those specified on this parameter. .PARAMETER Start The start date of the events to retrieve .PARAMETER Finish The end date of the events to retrieve. .PARAMETER Recurse A switch indicating if the events for the children of the Entity will also be returned .PARAMETER User The list of usernames for which events will be returned .PARAMETER System A switch that allows the selection of all system events. .PARAMETER ScheduledTask The name of a scheduled task for which the events will be returned .PARAMETER FullMessage A switch indicating if the full message shall be compiled. This switch can improve the execution speed if the full message is not needed. .EXAMPLE PS> Get-VIEventPlus -Entity $vm
      .EXAMPLE
      PS> Get-VIEventPlus -Entity $cluster -Recurse:$true
      #>

      param(
      [VMware.VimAutomation.ViCore.Impl.V1.Inventory.InventoryItemImpl[]]$Entity,
      [string[]]$EventType,
      [DateTime]$Start,
      [DateTime]$Finish = (Get-Date),
      [switch]$Recurse,
      [string[]]$User,
      [Switch]$System,
      [string]$ScheduledTask,
      [switch]$FullMessage = $false
      )

      process {
      $eventnumber = 100
      $events = @()
      $eventMgr = Get-View EventManager
      $eventFilter = New-Object VMware.Vim.EventFilterSpec
      $eventFilter.disableFullMessage = ! $FullMessage
      $eventFilter.entity = New-Object VMware.Vim.EventFilterSpecByEntity
      $eventFilter.entity.recursion = &{if($Recurse){"all"}else{"self"}}
      $eventFilter.eventTypeId = $EventType
      if($Start -or $Finish){
      $eventFilter.time = New-Object VMware.Vim.EventFilterSpecByTime
      if($Start){
      $eventFilter.time.beginTime = $Start
      }
      if($Finish){
      $eventFilter.time.endTime = $Finish
      }
      }
      if($User -or $System){
      $eventFilter.UserName = New-Object VMware.Vim.EventFilterSpecByUsername
      if($User){
      $eventFilter.UserName.userList = $User
      }
      if($System){
      $eventFilter.UserName.systemUser = $System
      }
      }
      if($ScheduledTask){
      $si = Get-View ServiceInstance
      $schTskMgr = Get-View $si.Content.ScheduledTaskManager
      $eventFilter.ScheduledTask = Get-View $schTskMgr.ScheduledTask |
      where {$_.Info.Name -match $ScheduledTask} |
      Select -First 1 |
      Select -ExpandProperty MoRef
      }
      if(!$Entity){
      $Entity = @(Get-Folder -Name Datacenters)
      }
      $entity | %{
      $eventFilter.entity.entity = $_.ExtensionData.MoRef
      $eventCollector = Get-View ($eventMgr.CreateCollectorForEvents($eventFilter))
      $eventsBuffer = $eventCollector.ReadNextEvents($eventnumber)
      while($eventsBuffer){
      $events += $eventsBuffer
      $eventsBuffer = $eventCollector.ReadNextEvents($eventnumber)
      }
      $eventCollector.DestroyCollector()
      }
      $events
      }
      }

      $Start = (Get-Date).AddDays(-31)
      Get-VIEventPlus -Start $start -EventType AlarmClearedEvent |
      Select CreatedTime,UserName,FullFormattedMessage

    Sam

    hi LucD
    my custom told me must be used the power cli to distable or enabel the alarm state ,i have used your script verygood haha thinks a lot 🙂

    Rajan

    Is this script working with PowerCli 5.1 Release 2. I am getting below error while running set-Alarmactionstate function

    Exception calling “EnableAlarmActions” with “2” argument(s): “The object has already been deleted or has not been completely created”
    At line:38 char:7
    + $alarmMgr.EnableAlarmActions($_.Extensiondata.MoRef,$Enabled)
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : VimException

    Michael

    Hi Luc,

    I´ve tried your code into PowerCLI 5.1 but I doesn´t work. I got te following error:

    Get-AlarmActionState : Die Argumenttransformation für den Parameter "Entity" kann nicht verarbeitet werden. Der Wert "HAL-PROD_CL1" vom Typ "System.String" kann nicht in den Typ "VMware.VimAutomation.ViCore.Impl.V1.Inventory.InventoryItemImpl" konvertiert werden.
    Bei Zeile:1 Zeichen:29
    + Get-AlarmActionState -Entity <<<< HAL-PROD_CL1
    + CategoryInfo : InvalidData: (:) [Get-AlarmActionState], ParameterBindin...mationException
    + FullyQualifiedErrorId : ParameterArgumentTransformationError,Get-AlarmActionState

    Do you know the problem and how I could solve it? THis would be fine.

    Thanks

    Vman

    Don’t know what I’m doing wrong. If I save this as a ps1 file and run it from powercli, I get nothing.

    If try to run the Get-AlarmActionstate sample code, I get Errors running Get-alarmtionactionstate. (sigh)

    What am I missing?

      LucD

      @Vman, when you download functions you have to save them in a .ps1 file. That .ps1 on itself will not do anything.
      To make the 2 functions usable from the PS prompt or in your own scripts, you will have to dot-source the .ps1 file containing the functions.

      PS C:\Scripts> . ./functions.ps1

      There is a blank between the 2 dots, and it assumes the .ps1 file is saved in the folder C:\Scripts.
      Once this is done, you can call any of the 2 functions as shown in the Sample Usage section.

        Sam

        @LucD,i have save the Script to the “C:\Sctriptis\” named functions.ps1.
        i open the powercli and run “C:\Scripts> . ./functions.ps1” after this
        PowerCLI C:\> c:\Scripts>../functions.ps1
        无法将“c:\Scripts>../functions.ps1”项识别为 cmdlet、函数、脚本文件或可运行程
        序的名称。请检查名称的拼写,如果包括路径,请确保路径正确,然后重试。
        所在位置 行:1 字符: 28
        + c:\Scripts>../functions.ps1 <<<../functions.ps1:Str
        ing) [], CommandNotFoundException
        + FullyQualifiedErrorId : CommandNotFoundException

        PowerCLI C:\>

    Neil

    Interesting article, it’s exactly what I’m looking for. However, when I run the function Get-AlarmActionState, I get the following error:

    Unexpected token ‘State’ in expression or statement.
    At line:25 char:33
    + $objects = @($Entity)State <<<<
    + CategoryInfo : ParserError: (State:String) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : UnexpectedToken

    I'll see if I can work it out, but just thought I'd give you a heads up.

    Regards

      admin

      Thanks Neil, good catch.
      That “State” shouldn’t be there. I updated the post.
      Sorry about that

Leave a Reply

Your email address will not be published. Required fields are marked *

*
*

This site uses Akismet to reduce spam. Learn how your comment data is processed.