codewario
codewario

Reputation: 21418

How do I get events associated with Datastores and Datastore Clusters using PowerCLI?

This is a followup to this question I posted but running into an issue with enumerating events on some objects now. When I run the following code (or try any of the solutions in my prior question) to get the events from a datastore or datastore cluster for example:

Get-VMFolder FOLDER_NAME -Type Datastore | Get-DatastoreCluster | Get-VIEvent

I'm met with the following error for each event it tries to return:

Events can be retrieved only for inventory objects. The entity of type
'VMware.VimAutomation.ViCore.Impl.V1.DatastoreManagement.VmfsDatastoreImpl' will be ignored.

This is particularly annoying since the cmdlet clearly enumerates the events as I get this error for every event it attempts to return.


When I use the Get-TaskPlus function mentioned in the accepted answer to my prior question returns a different type conversion error:

Cannot process argument transformation on parameter 'Entity'. Cannot convert the "DATASTORE_CLUSTER_NAME" value of type "VMware.VimAutomation.ViCore.Impl.V1.DatastoreManagement.DatastoreClusterImpl" to type "VMware.VimAutomation.ViCore.Impl.V1.Inventory.InventoryItemImpl".

If I remove the type constraint on the $Entity argument in the function definition, the error goes away but I also don't get any results.

I'm not really looking for recommendations or tools here, but if Get-VIEvent to look for events on non-inventory objects through PowerCLI, is there a workaround or more nuanced way to retrieve this information with PowerCLI?

Upvotes: 1

Views: 1011

Answers (1)

codewario
codewario

Reputation: 21418

After I posted this I did some more digging and found that Luc Dekens wrote another function called
Get-VIEventPlus. This doesn't work out of the box because -Entity expects a type of VMware.VimAutomation.ViCore.Impl.V1.Inventory.InventoryItemImpl[], but datastores and datastore clusters have a different type under the VMWare.VimAutomation.ViCore.Impl.V1.DatastoreManagement namespace.

If we make one change to LucD's function to accept the base type VMware.VimAutomation.ViCore.Impl.V1.VIObjectImpl[] instead of InventoryItemImpl[], Get-VIEventPlus should work other vCenter object types:

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.VIObjectImpl[]]$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
  }
}

Update: The original answer changed the -Entity type to be an object[]. I have updated this function to make use of the VMware.VimAutomation.ViCore.Impl.V1.VIObjectImpl[] base type for -Entity instead.

Upvotes: 1

Related Questions