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

by Grzegorz Kulikowski

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:

DESCRIPTION
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 :
[sourcecode language=”powershell”]
#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
[/sourcecode]
That will be faster then getting vm by it’s name using get-vm cmdlet.
[sourcecode language=”powershell”]
#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
[/sourcecode]

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:
[sourcecode language=”powershell”]
measure-command {Get-VMEvents -name testvm9999 -types "VmCreatedEvent"}
[/sourcecode]
Seconds : 1
Milliseconds : 506
Ticks : 15062052
[sourcecode language=”powershell”]
measure-command {get-vm testvm9999 |get-vievent| ?{$_ -is [vmware.vim.VmCreatedEvent]} }
[/sourcecode]
Seconds : 6
Milliseconds : 924
Ticks : 69241100

And the function 😉

[sourcecode language=”powershell”]
function Get-VMEvents {
<#
.Synopsis

Get events for an entity or for query all events.

.Description

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.

.Example

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

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

.Example

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 😉

.Example

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
events.

.Example

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
well.

.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.

.Notes

NAME: Get-VMEvents

AUTHOR: Grzegorz Kulikowski

LASTEDIT: 11/09/2012

NOT WORKING ? #powercli @ irc.freenode.net

.Link

http://psvmware.wordpress.com

#>

param(
[Parameter(ValueFromPipelineByPropertyName=$true)]
[string]$name,
[String[]]$types,
[string]$category
)
$si=get-view ServiceInstance
$em= get-view $si.Content.EventManager
$EventFilterSpec = New-Object VMware.Vim.EventFilterSpec
$EventFilterSpec.Type = $types
if($category){
$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
$em.QueryEvents($EventFilterSpec)
}else {
$em.QueryEvents($EventFilterSpec)
}
}
[/sourcecode]

You may also like

8 comments

JD November 19, 2012 - 6:58 pm

Thanks so much for this.. I hope it’s useful for someone other than me!

Cheers!

JD

Reply
Edvinas January 31, 2013 - 4:11 pm

thanks. it’s really useful 🙂

Reply
Consultant March 18, 2013 - 10:40 pm

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.

Reply
Consultant March 27, 2013 - 3:56 pm

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

}

I’ll post the full solution here
http://markvcp.blogspot.com/
and
here
http://www.facebook.com/vmware.vcp/notes

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

Reply
Consultant March 27, 2013 - 3:59 pm

Ooops. http://vmwarevcp.blogspot.com/ is not my blog. Error, sorry. Meant to say: http://markvcp.blogspot.com/

Reply
psvmware March 27, 2013 - 3:21 pm

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.

Reply
Daniel Petcher November 14, 2020 - 1:21 am

I love this script; It’s so much faster than Get-VM | Get-VIEvent. I needed just a little more filtering to capture RECENT events, so I followed your excellent example and extended the code:

param(
[Parameter(ValueFromPipelineByPropertyName = $true)]
[string]$name,
[String[]]$types,
[string]$category,
[System.DateTime]$StartTime
)
$si = get-view ServiceInstance
$em = get-view $si.Content.EventManager
$EventFilterSpec = New-Object VMware.Vim.EventFilterSpec
$EventFilterSpec.Type = $types
if ($StartTime) {
$EventFilterSpecByTime = New-Object VMware.Vim.EventFilterSpecByTime
$EventFilterSpecByTime.BeginTime = $StartTime
$EventFilterSpec.Time = $EventFilterSpecByTime
}
if ($category) {
$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
$em.QueryEvents($EventFilterSpec)
}
else {
$em.QueryEvents($EventFilterSpec)
}
}

Reply
Grzegorz Kulikowski November 14, 2020 - 9:08 am

Hi Daniel, it has been some times since i wrote that 😉 Please be aware of the fact that this is ‘short’ solution, as it it not getting all events in case there will be more than the first collection size, i wrote another some some time ago that actually handles is
https://grzegorzkulikowski.info/2015/07/29/get-gevents-for-getting-vsphere-events-with-some-additional-filtering/

Reply

Leave a Reply

Chinese (Simplified)EnglishFrenchGermanHindiPolishSpanish