Get-gEvents for getting vsphere events with some additional filtering

by Grzegorz Kulikowski

Some time ago i wrote a dirty function that utilizes eventfilterspec to filter out events. I knew it had one flaw, because as far as i remember i was using there QueryEvents method. Nothing bad with that, but as far as i understand it will only return up to 1000 records. So i have finally modified it so it uses EventCollector. It has support for searching by eventchainID, eventTypeId, username, date. I have tried to document function as much as possible. For me it works ok. There is some tiny support for checking eventTypeIds inside the function. If something is not clear make sure you will read the help
get-help get-gEvents -full
One confusing bit might be that while passing the entityname , you have to pass the viewtype as well. Well i did it because i use it this way 😉 So i use Get-View -ViewType [type] -Filter @{‘name’=XXX’}
So it’s up to you what exactly you are looking for, while specifying the entity, In filter name will be put, but ViewType specifies the type of object, whether it will be a datacenter, vm , cluster, datastore etc..
I tried to implement the switch for enabling/disabling full formatted message, but for some reason it was not working, no idea why.

Quick examples:

How to check how many vmotions DRS has performed inside a particular cluster ?

[sourcecode language=”powershell”]
(Get-gEvents -StartDate (get-date).AddDays(-1) -types ‘VmBeingHotMigratedEvent’ -EntityName ‘Cluster_name’ -ViewType ClusterComputeResource).Count
[/sourcecode]

How to check how many vmotions DRS has performed inside a particular datacenter ?

[sourcecode language=”powershell”]
(Get-gEvents -StartDate (get-date).AddDays(-1) -types ‘VmBeingHotMigratedEvent’ -EntityName ‘Datacenter_name’ -ViewType Datacenter).count
[/sourcecode]

Endless possibilities basically.. i will throw 1 more
How many times user X has powered off a VM in last 7 days

[sourcecode language=”powershell”]
(Get-gEvents -StartDate (get-date).AddDays(-7) -EventTypeIds ‘VmPoweredOffEvent’ -EventUsername ‘DOMAIN\UserX’ -systemUser:$false ).count
[/sourcecode]

How many were there vmotions in some cluster during last 7 days

[sourcecode language=”powershell”]
Get-gEvents -StartDate (get-date).AddDays(-7) -EventTypeIds ‘VmFailedMigrateEvent’ -EntityName ‘SomeCluster’ -ViewType ClusterComputeResource}
[/sourcecode]

What if you want to check for other dates ? Use: -StartDate with (get-date).AddDays(-7) for example, to go 7 days back. Same goes for end date, -EndDate (get-date…..

When you will be giving parameter for the Entity, you can still use the -Recursion parameter with it to control whether you want to inspect only THAT entity, or its children, or both.

If you will skip -startdate or -enddate make sure you know that function is setting those variable up anyway with default values of: Enddate -> NOW , -startdate 7 days ago.

Make sure you know that by default if you will skip those parameters : systemuser and recursion will be set to true and all . So if you wonder how come you received system events if you were looking for user’s events, mark the -systemuser:$false , if you want to look only for event on entity and do not want to step inside its children use -recursion ‘self’ , because by default i set it to ‘all’.

You do not need to provide entity for this function to start, if not given it searches through everything.

Enjoy

[sourcecode language=”powershell”]
function Get-gEvents
{

[cmdletbinding(DefaultParametersetName = “Main Usage”)]
param (
[parameter(Mandatory = $true, ParameterSetName = “Main Events Types Listing”)][switch]$ListMainEVTypes,
[parameter(Mandatory = $true, ParameterSetName = “Detailed SubEvents Types Listing”)][switch]$ListSecEVTypes,
[parameter(Mandatory = $true, ParameterSetName = “Detailed SubEvents Types Listing”)]$SubEVType,
[parameter(Mandatory = $true, ParameterSetName = “ChainID Events Listing”)][string]$eventChainId,
[parameter(Mandatory = $false, ParameterSetName = “Main Usage”)][string[]]$EventUsername,
[parameter(Mandatory = $false, ParameterSetName = “Main Usage”)][bool]$systemUser = $true,
[parameter(Mandatory = $false, ParameterSetName = “Main Usage”)][string]$EntityName,
[parameter(Mandatory = $false, ParameterSetName = “Main Usage”)][String[]]$EventTypeIds,
[parameter(Mandatory = $false, ParameterSetName = “Main Usage”)][VMware.Vim.EventCategory]$category,
[parameter(Mandatory = $false, ParameterSetName = “Main Usage”)][datetime]$StartDate = (Get-Date).AddDays(-7),
[parameter(Mandatory = $false, ParameterSetName = “Main Usage”)][datetime]$EndDate = (Get-date),
[parameter(Mandatory = $false, ParameterSetName = “Main Usage”)][vmware.vim.EventFilterSpecRecursionOption]$Recursion = ‘all’,
[parameter(Mandatory = $false, ParameterSetName = “Main Usage”)][ValidateSet(‘ClusterComputeResource’, ‘ComputeResource’, ‘Datacenter’, ‘Datastore’, ‘DistributedVirtualPortgroup’, ‘DistributedVirtualSwitch’, ‘Folder’, ‘HostSystem’, ‘Network’, ‘OpaqueNetwork’, ‘ResourcePool’, ‘StoragePod’, ‘VirtualApp’, ‘VirtualMachine’, ‘VmwareDistributedVirtualSwitch’)][string]$ViewType
)

switch ($PsCmdlet.ParameterSetName)
{
“Main Events Types Listing” {
[VMware.Vim.VmEvent].Assembly.GetTypes() | ? { $_.BaseType -eq [VMware.Vim.Event] }
break

}
“Detailed SubEvents Types Listing” {

[VMware.Vim.VmEvent].Assembly.GetTypes() | ? { $_.BaseType -like “VMware.Vim.$SubEVType” }
break
}
“Main Usage” {
$si = get-view -id ServiceInstance
$em = get-view -id $si.Content.EventManager

$EventFilterSpec = New-Object VMware.Vim.EventFilterSpec
$EventFilterSpec.eventTypeId = $EventTypeIds
if ($StartDate -or $EndDate)
{
Write-debug “Date was given”
$EventFilterSpec.Time = New-Object Vmware.Vim.EventFilterSpecByTime
$EventFilterSpec.Time.beginTime = $StartDate
$EventFilterSpec.Time.endTime = $EndDate
}
if ($category)
{
Write-debug “Category was given”
$EventFilterSpec.Category = $category
}
if ($EventUsername)
{
Write-debug “User was given”
$EventFilterSpec.userName = New-Object Vmware.Vim.EventFilterSpecByUsername
$EventFilterSpec.userName.systemUser = $systemUser
$EventFilterSpec.userName.userList = $EventUsername
}
if ($EventChainId)
{
Write-debug “EventChainId was given”
$EventFilterSpec.EventChainId = $EventChainId
}
if ($EntityName)
{
Write-debug “Entity was given”
$entity = get-view -viewtype $ViewType -Filter @{ ‘name’ = “^$EntityName$” } -Property name
$EventFilterSpec.Entity = New-Object VMware.Vim.EventFilterSpecByEntity
$EventFilterSpec.Entity.Entity = $entity.moref
$EventFilterSpec.Entity.Recursion = $Recursion
}
$EventCollector = get-view -id $EM.CreateCollectorForEvents($Eventfilterspec)
$EventCollector.RewindCollector()
write-debug “Collector rewinded”
$events = $null

while ($EventInWindow = $EventCollector.ReadNextEvents(100))
{
$Events += $EventInWindow
write-debug “Reading next window”
}
$EventCollector.DestroyCollector()
$Events
break}
}

}

[/sourcecode]

You may also like

2 comments

Jonathan August 27, 2019 - 9:37 pm

I had an error related to EventFilterSpecByEntity, I realized it was because the EntityName matched 2 clusters so I changed the filter on line 66 with this: @{ ‘name’ = “^$EntityName$” }

Reply
psvmware August 28, 2019 - 8:59 am

Thank you Jonathan for spotting this !

Reply

Leave a Reply

Chinese (Simplified)EnglishFrenchGermanHindiPolishSpanish