Alarms – Moving them around

You should know by now that alarms are a powerful tool to help you manage and monitor your vSphere environment.  But in my opinion there is a basic operation missing.

There is no easy way to move an alarms from one entity to another entity. No drag-and-drop in the vSphere Client, no Move-Alarm cmdlet in PowerCLI.

A practical example, you have developed this fantastic new alarm and for testing purposes you had defined it on a single virtual machine. Now the tests are done and your alarm is ready for production. But there is apparently no easy way to move your new alarm to the root of your vSphere environment.

Luckily we have PowerCLI and we can easily create a function to fill this gap.

The script

The function is called Move-Alarm and has the following syntax:

Move-Alarm -Alarm <Alarm> -From <ViContainer> -To <ViContainer[]> -DeleteOriginal

Alarm: the MoRef of the Alarm object you want to move
From: the ViContainer from where the alarm should be moved
To: one or more ViContainer objects to which the alarm should be moved
DeleteOriginal: a switch that determines what happens with the original alarm. Default is $false

Update 23/02/10

While using the script I discovered that the length of the name of an alarm can not exceed 80 characters. This seems to be an undocumented “feature”.

A second problem in the original script was that when you “move” to more than one destination, there would be an error message on the second “move”. That was because you can not have two alarms with the same name in your vCenter. The solution I used was to add the name of the destination entity as a suffix to the name of the new alarm.

The third problem was the Status property in each EventAlarmExpression object. Since the script copies the AlarmInfo object from the “from” alarm to the AlarmSpec object for the “to” alarm, the Status property has to blanked out explicitly.

Annotations

Line 1: The maximum length of the name of an Alarm defined as a constant.

Line 3-5: Variables that will be used later on in the script as parameters to the function. In the sample I’m moving all alarms from the vCenter root (hidden entity “Datacenters”) to two folders called “Folder1” and “Folder2”

Line 8: Note that the function doesn’t use strongly types parameters for the -From and -To parameters. This is because the ViObjects on which alarms can be defined can be of several types (Datacenter, Folder, HostSystem…). This also allows to pass an array of ViObjects for the -To parameter.

Line 14: If the -DeleteOriginal switch is set to $true, the original alarm will be deleted.

Line 17-35: If the -DeleteOriginal switch is set to $false the original Alarm will be kept but it will be renamed since there can not be multiple alarms with the same name.

Line 24,48: If the length of name with the suffix exceeds 80 characters, the script will remove sufficient characters from the original alarmname to be able to add the suffix.

Line 29: If the original alarm is kept it will be renamed. The original will get a suffix “(moved to <dest>)”

Line 30: If the original alarm is kept it will be “disabled”.

Line 31,54: The script adds the original alarmname to the Description field.

Line 32-37,64-69: Since the script copies the AlarmSpec object from the original alarm, the Status field for all the EventAlarmExpression objects needs to blanked out.

Line 52: The -To parameter is handled in a foreach loop since the function allows more than one destination. The function can be used as a 1-to-n move in this case.

Line 80-81: A sample use case of the Move-Alarm function. All Alarms defined in the root of the vCenter will be “moved” to “Folder1” and “Folder2”. The original Alarm will not be deleted but it will be renamed and disabled.

Samples

Before the run of the above sample use of the script, the alarms defined on the vCenter root look like this.

After the first call of the Move-Alarm function the first alarm has been changed and disabled.

And on both target folders the alarm has been created as this screenshot from the alarms on Folder1 shows.

This is a rather simple function but it can be quite useful at times. I hope it can be of use to some of you.

27 Comments

    Dan

    any updates for 6.x – I cannot get the script to work in 6.x

      LucD

      Sorry to hear that Dan.
      What kind of error are you getting?

    vmware_vs

    Hi Luc,

    This script works within a vCenter (betwen two folders / datacenters / clusters), I am looking for moving all alarms from one vcenter to anohter. Is it doable. Thanks

    ScR

    @BradS
    same problem here on vcenter 5.0 for move/copy on alarm.

    and for the german powercli:
    datacenters = datencenter (in line 3)

    Matthieu

    Hi Luc,

    Thanks a lot for your job! Did you try your script on a Vcenter 5.1b? with Power CLI5.1? I’ve got an issue when the script try to create the alarms.
    I need to copy all alarms from Vcenter (root) to 5 differents folders. Thanks a lot.

    BradS

    @LucD
    My Settings

    $alarm = (Get-AlarmDefinition -Name “Snapshots”).ExtensionData
    $from = Get-Folder -Name “Datacenters” | Get-View
    $to = Get-Cluster -Name “Dev_Test_Stage Cluster” | Get-View
    ___________________________________________________________________
    $alarmMgr = Get-View AlarmManager

    $alarms = $alarmMgr.GetAlarm($from.MoRef)
    $alarms | % {
    Move-Alarm -Alarm $alarm -From $from -To $to -DeleteOriginal:$false

    When I try to copy over just 1 Alarm I get this error message

    Get-View : Cannot bind parameter ‘Id’. Cannot convert the “VMware.Vim.Alarm” va
    lue of type “VMware.Vim.Alarm” to type “VMware.Vim.ManagedObjectReference”.

    Thanks,
    Brad

    Matt

    My situation, I need to copy all the alarms from the root, to a Cluster. I need to leave the main ones in the root alone, and then setup the notifications on the new ones in the cluster. The ones in the root will remain in use by another team.

    I finally edited your script to function and do all this, but all of my Triggers become “UnSet” so I have to go through and set them all up again, and I just noticed all my root ones became “UnSet” as well.

    Good thing I did this in a test environment, any help?

    Matt

    My situation is we have two groups that monitor alarms. They defined all theirs at the VCENTER root, we want to copy all the alarms to some clusters and set only specific ones up for ourselves.

    I finally got your script to perform this, copy all the alarms to a new folder and leave the current ones in place.

    The problem is when it is done, all the alarm triggers are “UnSet” which essentially borked all the triggers on both the original and the destination alarms.

    Any help?

    Matt

    I am trying to modify this script to copy an alarm from the VCENTER level and create a new unique alarm at the different cluster levels in our environment. What is an easy way to do this one alarm at a time, and not touch the original alarm? I only need to copy one alarm to one folder and make it unique. I am not a strong scripter with PowerCLI and am looking for the simplest method..

      LucD

      @Matt, similar questions came up in the PowerCLI Community.
      Have a look at export / store / delete / import alarms on many datacenters object and Script to Move/Copy All VC alarms from root folder to sub folder.
      Both threads contain updated version of the script.
      Have a look if those threads help you, otherwise feel free to come back.

    AlanR

    LucD, how do you take this script and make it move ALL alarms to a new folder. The reason is we find that having all alarms at the top level stop us from defining alarms for specific needs, based on buisness requiments and have a folder for them. So:-

    1) New folder all alarms are moved to, for general purpose
    2) Copy all alarms to second folder so they can be deleted/disabled as needed

    Thanks AlanR

    Mark

    Luc

    Thanks for this script. I hope you can help me understand how to move a single alarm from the root of the datacenter to a folder. I understand about changing the $from and $to lines at the top, but I’m uncertain how to select a single alarm. I tried modifying:

    Move-Alarm -Alarm “Virtual machine total disk latency” -From $from -To $to1 -DeleteOriginal:$false

    but that resulted in an error that the alarm wasn’t found. I don’t understand the syntax necessary to define the alarm properly for the get-view cmdlet.

      LucD

      @Mark, that function expects an Alarm object as a parameter. In other words a server-side, or SDK, object.
      You can do

      $alarm = (Get-AlarmDefinition -Name “Virtual machine total disk latency”).ExtensionData
      Move-Alarm -Alarm $alarm -From $from -To $to1 -DeleteOriginal:$false

      I hope this helps.

    CJ

    Luc,
    I can’t thank you enough for your time & effort. Thanks for an awesome book & for all your work. It is making me a better scripter and helping me to understand script writing but more specifically PowerCLI better. I look forward to the day when I can write scripts with the speed & proficiency that you do.

    Jon

    Hi Luc,

    I’m investigating migrating a set of defined alarms from one vCenter to another. I have a script that works if I have direct connection to both vCenters.

    I’m trying to work out how to perform the migration if I don’t have direct access to both vCenter servers simultaneously.

    Is there any way to export alarm(s) to output file(s) and then import them?

    Cheers,
    Jon

      LucD

      @Jon, in fact there is. I described the method in our book.
      The functions are available ion the Sybex website.
      You want the Get-AlarmScript function from chapter 16. This function will take an alarm and produce a .ps1 script that creates that same alarm. Once you have the .ps1 script, it’s a matter of executing that .ps1 script on the new vCenter.
      I hope this helps to solve your problem.

        mtopen14

        On a related note. I’ve tried to use the Get-AlarmScript function mentioned above, but I must be missing something. I get the following error when running the exported .ps1 script:

        Cannot convert argument “entity”, with value: “System.Object[]”, for “CreateAlarm” to type “VMware.Vim.ManagedObjectReference”: “Cannot convert the
        “System.Object[]” value of type “System.Object[]” to type “VMware.Vim.ManagedObjectReference”.”
        At C:\Temp\guest_cpu_alarm.ps1:70 char:1
        + $alarmMgr.CreateAlarm($entity.Extensiondata.MoRef,$spec)
        + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo : NotSpecified: (:) [], MethodException
        + FullyQualifiedErrorId : MethodArgumentConversionInvalidCastArgument

        The function I’ve used is verbatim:
        #requires -version 2
        #requires -pssnapin VMware.VimAutomation.Core -version 4.1

        $spec = New-Object VMware.Vim.AlarmSpec
        $spec.Name = “Guest CPU Alarm”
        $spec.Description = “”
        $spec.ActionFrequency = 0
        $spec.Enabled = $False

        $action = New-Object VMware.Vim.GroupAlarmAction

        $action1 = New-Object VMware.Vim.AlarmTriggeringAction
        $action1.Green2yellow = $False
        $action1.Red2yellow = $False
        $action1.Yellow2green = $False
        $action1.Yellow2red = $False
        $action1.Action = New-Object VMware.Vim.SendEmailAction
        $action1.Action.Body = “”
        $action1.Action.CcList = “”
        $action1.Action.Subject = “”
        $action1.Action.ToList = “sscopenintel@opensolutions.com;”

        $trans1 = New-Object VMware.Vim.AlarmTriggeringActionTransitionSpec
        $trans1.StartState = “yellow”
        $trans1.FinalState = “red”
        $trans1.Repeats = $False

        $action1.TransitionSpecs += $trans1

        $trans2 = New-Object VMware.Vim.AlarmTriggeringActionTransitionSpec
        $trans2.StartState = “green”
        $trans2.FinalState = “yellow”
        $trans2.Repeats = $False

        $action1.TransitionSpecs += $trans2

        $action.Action += $action1

        $spec.Action = $action

        $expression = New-Object VMware.Vim.OrAlarmExpression

        $expression1 = New-Object VMware.Vim.MetricAlarmExpression
        $expression1.metric = New-Object VMware.Vim.PerfMetricId
        $expression1.metric.counterId = 2
        $expression1.metric.instance = “”
        $expression1.operator = “isAbove”
        $expression1.red = 10000
        $expression1.redInterval = 120
        $expression1.type = “VirtualMachine”
        $expression1.yellow = 9500
        $expression1.yellowInterval = 120

        $expression.Expression += $expression1

        $spec.Expression = $expression

        $setting = New-Object VMware.Vim.AlarmSetting
        $setting.reportingFrequency = 0
        $setting.toleranceRange = 0

        $spec.Setting = $setting

        $entity = Get-Inventory -Name SCOM

        $alarmMgr = Get-View AlarmManager
        $alarmMgr.CreateAlarm($entity.Extensiondata.MoRef,$spec)

        Perhaps something has changed since 4.1 to alter the behavior?

    Oleg

    Luc,

    Did you see this KB https://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1026429?

    Per Vmware by disabling any alarm on object (VM, Host, etc.) you are disabling all alarms on the same objects on all VC; at least you should not count on them.

    Thanks,
    Oleg

      LucD

      Hi Oleg, thanks for the info.
      Yes, I know that KB, but this was a bug that is fixed in 4.1 Update 1.
      If you’re on 4.0 or 4.1, the described problem can indeed occur.

    Brad

    I’m afraid that I don’t understand the usage here — I have several alarms defined under the vCenter object and need them moved to a cluster level. Is that possible with this script? I’ve tried a couple things and all of my alarms end up getting renamed and disabled but not moved.

      LucD

      @Brad, the trick is in the setting of the To and From parameters.
      To move from the vCenter root to a specific cluster, you will have to replace the 3 lines at the beginning with

      $from = Get-Folder -Name "Datacenters" | Get-View
      $to = Get-Cluster -Name "MyCluster" | Get-View

      and the call to the actual function at the end will become

      $alarms = $alarmMgr.GetAlarm($from.MoRef)
      $alarms | % {
      Move-Alarm -Alarm $_ -From (Get-View $_) -To $to -DeleteOriginal:$false
      }

      Is that understandable ?
      Otherwise I’ll do a rewrite of that post and add some more examples.

    Conrad

    Out of curiousity, how long does it take you to write a script like this?

      LucD

      @Conrad, the classic answer it depends 🙂
      Seriously, most of the time my post ideas come from pieces of code that I already have.
      That code was created for a practical problem in our environment or as an answer to a post in the PowerCLI Community.
      For publication I have to generalise it, polish it up, test it and write the post.
      This particular one started of from some existing code and it took me 2 evenings to make the post ready for publication.

    Andrei Neagoe

    Hey Luc,

    In my case it would be nice to be able to copy the definitions from one vCenter to another. How should I tackle this? I’m not exactly sure how to use a script against two vCenter instances…

      LucD

      Hi Andrei,
      With the latest PowerCLI build you can configure PowerCLI to run in multi-mode, which means you can open several vCenters and specify on the cmdlets against which vCenter they should run (that’s mostly through the -Server parameter).
      Now this script use several SDK methods, where it is not so obvious to specify against which vCenter a SDK method should be executed.
      I would start by investigating how the AcquireCloneTicket and CloneSession methods could be used.
      But I’m not sure if that would solve the different sessions problems. It would require further investigation.
      Luc.

    sham

    Luc

    As always I admire your dedication to solving real world admin problems using powercli. I do a lot of work with alarms and can see this coming in use at some point.

    Can we take it this is your submission to the script-o-mania competition 🙂

      LucD

      Thanks Sham.
      No, this is not my Script-O-Mania submission (yet) 😉

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.