如何使用 PowerCLI 获取与数据存储和数据存储集群关联的事件?
How do I get events associated with Datastores and Datastore Clusters using PowerCLI?
这是我发布的 的后续内容,但现在 运行 遇到了在某些对象上枚举事件的问题。例如,当我 运行 以下代码(或尝试我之前问题中的任何解决方案)从数据存储或数据存储集群获取事件时:
Get-VMFolder FOLDER_NAME -Type Datastore | Get-DatastoreCluster | Get-VIEvent
对于它尝试的每个事件,我都遇到了以下错误 return:
Events can be retrieved only for inventory objects. The entity of type
'VMware.VimAutomation.ViCore.Impl.V1.DatastoreManagement.VmfsDatastoreImpl' will be ignored.
这特别烦人,因为 cmdlet 清楚地 枚举了事件,因为我为它尝试 return.
的每个事件都收到此错误
当我使用 中提到的 Get-TaskPlus
函数来解决我之前的问题 returns 一个不同的类型转换错误:
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".
如果我在函数定义中删除 $Entity
参数的类型约束,错误就会消失,但我也不会得到任何结果。
我并不是真的在这里寻找建议或工具,但如果 Get-VIEvent
通过 PowerCLI 查找非清单对象上的事件,是否有解决方法或更细微的方法来使用 PowerCLI 检索此信息?
在我发布这篇文章之后,我做了更多的挖掘,发现 Luc Dekens 写了另一个函数,叫做
Get-VIEventPlus
。这不是开箱即用的,因为 -Entity
需要 VMware.VimAutomation.ViCore.Impl.V1.Inventory.InventoryItemImpl[]
类型,但数据存储和数据存储集群在 VMWare.VimAutomation.ViCore.Impl.V1.DatastoreManagement
命名空间下具有不同的类型。
如果我们对 LucD 的函数进行一项更改以接受基本类型 VMware.VimAutomation.ViCore.Impl.V1.VIObjectImpl[]
而不是 InventoryItemImpl[]
,Get-VIEventPlus
应该可以使用其他 vCenter 对象类型:
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
}
}
更新:原始答案将 -Entity
类型更改为 object[]
。我已经更新了此函数以使用 VMware.VimAutomation.ViCore.Impl.V1.VIObjectImpl[]
基类型代替 -Entity
。
这是我发布的
Get-VMFolder FOLDER_NAME -Type Datastore | Get-DatastoreCluster | Get-VIEvent
对于它尝试的每个事件,我都遇到了以下错误 return:
Events can be retrieved only for inventory objects. The entity of type
'VMware.VimAutomation.ViCore.Impl.V1.DatastoreManagement.VmfsDatastoreImpl' will be ignored.
这特别烦人,因为 cmdlet 清楚地 枚举了事件,因为我为它尝试 return.
的每个事件都收到此错误当我使用 Get-TaskPlus
函数来解决我之前的问题 returns 一个不同的类型转换错误:
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".
如果我在函数定义中删除 $Entity
参数的类型约束,错误就会消失,但我也不会得到任何结果。
我并不是真的在这里寻找建议或工具,但如果 Get-VIEvent
通过 PowerCLI 查找非清单对象上的事件,是否有解决方法或更细微的方法来使用 PowerCLI 检索此信息?
在我发布这篇文章之后,我做了更多的挖掘,发现 Luc Dekens 写了另一个函数,叫做 Get-VIEventPlus
。这不是开箱即用的,因为 -Entity
需要 VMware.VimAutomation.ViCore.Impl.V1.Inventory.InventoryItemImpl[]
类型,但数据存储和数据存储集群在 VMWare.VimAutomation.ViCore.Impl.V1.DatastoreManagement
命名空间下具有不同的类型。
如果我们对 LucD 的函数进行一项更改以接受基本类型 VMware.VimAutomation.ViCore.Impl.V1.VIObjectImpl[]
而不是 InventoryItemImpl[]
,Get-VIEventPlus
应该可以使用其他 vCenter 对象类型:
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
}
}
更新:原始答案将 -Entity
类型更改为 object[]
。我已经更新了此函数以使用 VMware.VimAutomation.ViCore.Impl.V1.VIObjectImpl[]
基类型代替 -Entity
。