get-vievent too slow ? :) BOOSTING get-vievent !

There was quite interesting question on communities today. I think it’s worth to share it with everybody what and how 😉
Right so, let’s say you want to get some events from entities using get-vievent:

Retrieves information about the events on a vSphere server. An event is any action in the vCenter Server system or ESX host. The cmdlet collects events that correspo
ned by the cmdlet parameters. Filters are additive and the Entity. Start, and Finish parameters filter the events both by the entity and the timestamp properties. To
om the default one, use the -Server parameter.

So ok, if you have entity, like cluster, vm, resourcepool, etc… you can use that as VIObject for get-vievent. There few things worth to mention here:
Doing :
get-vm |Get-vievent
is probably not the best idea 😉 It leaves too many options. I guess you do not have hobby to view ALL events for vms from time to time 😉 Anyway, we are loosing time
get-vm (looosing time to get vm objects) | get-vievent
you can’t enter here with only get-view to pass result to get-vievent as that will fail because of wrong object type. Get-viobjectbyviview to the rescue here! So guess what :

#18:52:11> measure-command {get-view -viewtype virtualmachine -Filter @{'name'='testvm9999'}|get-viobjectbyviview|Get-VIEvent|?{$_ -is [Vmware.vim.VmCreatedEvent]} }

Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 2
Milliseconds      : 907
Ticks             : 29077235

That will be faster then getting vm by it’s name using get-vm cmdlet.

#18:18:45> measure-command {get-vm testvm9999|Get-VIEvent|?{$_ -is [Vmware.vim.VmCreatedEvent]} }
Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 6
Milliseconds      : 860
Ticks             : 68601261

So the question was how to get all events regardless if it’s for vm A or for vm B so it would be quite fast. get-vievent without specifying entity will do the trick here as well. It’s just that it will take some time to finish that . In order to cook this we need:
1) EventManager
2) QueryEvents method from 1)
3) Know how to use 2) 🙂 so how to create EventFilterSpec
4) In case we want to run QueryEvents against 1 entity we need to know how to create EventFilterSpecByEntity

Alright, ready ?
Open 1, Event Manager will be obtained from content of service instance. Once we will have Event Manager we can proceed to build the filter. Filter consists of different properties, it’s up to you which one would you like to implement. I have used in my function, category,entity,type . You can use Time if you want to search for events that have occurred within some specific time window. By default when entity property is not defined it will go thorough all events that VC has. When you want to filter only events for entity : “vm1″, you can use the entity property. This type :”EventFilterSpecByEntity” consist of moref and a recursion. In this particular case when i wrote this function for vms ONLY, ManagedObjectReference (moref) will be taken from get-view. Regarding recursion i do not need to set it here as i am operating only on vm object.
Once we have built our filter we can go ahead and run our method: QueryEvents(which takes the filter as the argument)

And my function regarding this topic. If something is not clear run help:
get-help get-vmevent -full
If somethings is wrong, uhm… well, it can happen to anyone right ? please make a comment pointing where i made something wrong 😉
Results in my environment:

measure-command {Get-VMEvents -name testvm9999 -types "VmCreatedEvent"}

Seconds : 1
Milliseconds : 506
Ticks : 15062052

measure-command {get-vm testvm9999 |get-vievent| ?{$_ -is [vmware.vim.VmCreatedEvent]} }

Seconds : 6
Milliseconds : 924
Ticks : 69241100

And the function 😉

function Get-VMEvents {

    Get events for an entity or for query all events.


    This function returns events for entities. It's very similar to 
	get-vievent cmdlet.Note that get-VMEvent can handle 1 vm at a time.
	You can not send array of vms in this version of the script.


    Get-VMEvents -types "VmCreatedEvent","VmDeployedEvent","VmClonedEvent"

    This will receive ALL events of types "VmCreatedEvent","VmDeployedEvent",

    Get-VMEvents -name 'vm1' -types "VmCreatedEvent"

    Will ouput creation events for vm : 'vm1'. This was is faster than piping vms from
	get-vm result. There is no need to use get-vm to pass names to get-vmevents.
	Still, it is ok when you will do it, it will make it just a little bit slower 😉

    Get-VMEvents -name 'vm1' -category 'warning'

    Will ouput all events for vm : 'vm1'. This was is faster than piping names from
	get-vm cmdlet. Category will make get-vmevent to search only defined category

    get-vm 'vm1' | Get-VMEvents -types "VmCreatedEvent","VmMacAssignedEvent"

    Will display events from vm1 which will be regarding creation events,
	and events when when/which mac address was assigned

	.Parameter name

    This parameter is a single string representing vm name. It expects single vm name that
	exists in virtual center. At this moment in early script version it will handle only a case
	where there is 1 instance of vm of selected name. In future it will handle multiple as 
   .Parameter types

    If none specified it will return all events. If specified will return
	only events with selected types. For example : "VmCreatedEvent",
	"VmDeployedEvent", "VmMacAssignedEvent" "VmClonedEvent" , etc...
	.Parameter category

    Possible categories are : warning, info, error. Please use this parameter if you
	want to filter events.


    NAME:  Get-VMEvents

    AUTHOR: Grzegorz Kulikowski

    LASTEDIT: 11/09/2012
	NOT WORKING ? #powercli @ 



    $si=get-view ServiceInstance
    $em= get-view $si.Content.EventManager
    $EventFilterSpec = New-Object VMware.Vim.EventFilterSpec
	$EventFilterSpec.Type = $types
	$EventFilterSpec.Category = $category
	if ($name){
	$vmentity = get-view -ViewType virtualmachine -Filter @{'name'=$name}
	$EventFilterSpec.Entity = New-Object VMware.Vim.EventFilterSpecByEntity
	$EventFilterSpec.Entity.Entity = $vmentity.moref
	}else {

6 thoughts on “get-vievent too slow ? :) BOOSTING get-vievent !

  1. Using this method, how do I get more than 1000 events? I could find not property or method for setting the “MaxSamples” for the EventFilterSpec or EventManager.

    • I figured it out.

      There are 2 interesting methods on TaskManager and EventManager.
      Name MemberType
      —- ———-
      ReadNextEvents Method
      ReadPreviousEvents Method
      ResetCollector Method #### Sets the queue to the End of the Log
      RewindCollector Method #### Sets queue to the Beginning of the log
      SetCollectorPageSize Method ### Could not get this method to work for me in vSphere 4.* and 5.1
      SetViewData Method

      This is how I did it:
      while ($SomethingNotFound){

      $TaskCount = 1000
      $events = $em.ReadPreviousTasks($TaskCount) # reads previous 1000 events/log entries and
      $SomethingNotFound = $events | ? { $_.DescriptionID -match “Something” }


      I’ll post the full solution here

      BTW, many thanks to the person who posted this initial blog entry.

  2. Consultant: Hi there, still trying to figure this out hehehe 😉 need to understand this page idea, for me it works currently in the same way as for you , you get ‘ALL’, and then you rewind or move forward with a counter . Still you could decrease the amount of events by giving it in filter.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s