Hi Folks,
I need some help in creating the cmdlet or script to show Error and Warning VI Events in the vCenter in the past 1 hour?
I have stumbled upon this article: Get the vMotion/svMotion history - LucD notes
But not sure how to build the cmd line so this can be scripted every 1 hour using scheduled task.
Thank you in advance.
Yes, it can.
The EventFilterSpec contains a property named Category.
In there, you can enter one or more of the EventCategory values (Error,Info,User,Warning).
This updated version makes that option available.
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.
.PARAMETER Category
Limits the set of collected events to those associated with the specified category
.EXAMPLE
PS> Get-VIEventPlus -Entity $vm
.EXAMPLE
PS> Get-VIEventPlus -Entity $cluster -Recurse:$true
.EXAMPLE
PS> Get-VIEventPlus -Entity $cluster -Category 'error','warning'
#>
param(
[VMware.VimAutomation.ViCore.Impl.V1.Inventory.InventoryItemImpl[]]$Entity,
[string[]]$EventType,
[DateTime]$Start,
[DateTime]$Finish = (Get-Date),
[switch]$Recurse,
[string[]]$User,
[Switch]$System,
[string]$ScheduledTask,
[switch]$FullMessage = $false,
[string[]]$Category
)
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
$eventFilter.Category = $Category
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
}
}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
I'm not sure what exactly you want to retrieve.
All events for the past hour, or specific events for the past hour?
To prepare, copy the Get-VIEventPlus function to a .ps1 file (for example GetVIEventPlus.ps1).
Then dot-source that .ps1 file (note the space betwene the 2 dots at the start of the line), this makes sure that your PS sessions "knows" the function.
. .\GetVIEventPlus.ps1
Now you can "call" the function.
If you just want to retrieve all events created against the root of the vCenter for the last hour, you can do
Get-VIEventPlus -Start (Get-Date).AddHours(-1)
If you want all events in the vCenter for the last hour, you can do
Get-VIEventPlus -Start (Get-Date).AddHours(-1) -Recurse
If you want specific events, you could do
Get-VIEventPlus -Start (Get-Date).AAddHours(-1) -EventType 'DrsVmMigratedEvent','VmMigratedEvent'
If you have more specific requirements, let me know.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Hi @LucD ,
Thank you for the reply.
May I know if the script can be used or customized to show the result for any Error, Critical or Failed events in the past 1 hour?
Yes, it can.
The EventFilterSpec contains a property named Category.
In there, you can enter one or more of the EventCategory values (Error,Info,User,Warning).
This updated version makes that option available.
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.
.PARAMETER Category
Limits the set of collected events to those associated with the specified category
.EXAMPLE
PS> Get-VIEventPlus -Entity $vm
.EXAMPLE
PS> Get-VIEventPlus -Entity $cluster -Recurse:$true
.EXAMPLE
PS> Get-VIEventPlus -Entity $cluster -Category 'error','warning'
#>
param(
[VMware.VimAutomation.ViCore.Impl.V1.Inventory.InventoryItemImpl[]]$Entity,
[string[]]$EventType,
[DateTime]$Start,
[DateTime]$Finish = (Get-Date),
[switch]$Recurse,
[string[]]$User,
[Switch]$System,
[string]$ScheduledTask,
[switch]$FullMessage = $false,
[string[]]$Category
)
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
$eventFilter.Category = $Category
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
}
}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Wow, thank you @LucD for the assistance in this thread.
I wonder what am I missing in the below code to iterate through all of my vCenters:
$connectVIServer = @'
"Server", "User", "Password"
"10.10.10.10", "DOMAIN\VI-Admin1", "Pass1"
"20.20.20.20", "DOMAIN\VI-Admin2", "Pass2"
"99.99.99.99", "DOMAIN\VI-AdminX", "PassX"
'@ | ConvertFrom-Csv
ForEach ($row in $connectVIServer)
{
Write-Host "Connecting to '$($row.Server)'".
$paramConnectVIServer = @{
Server = $row.Server
User = $row.User
Password = $row.Password
}
Connect-VIServer @paramConnectVIServer
$paramGetVIEventPlus = @{
Recurse = $true
Entity = $_
Category = 'error', 'warning', 'user', 'info'
}
$AllEvents += Get-Cluster | Get-VIEventPlus @paramGetVIEventPlus
$paramDisconnectVIServer = @{
Server = $paramConnectVIServer.Server
Force = $true
}
Disconnect-VIServer @paramDisconnectVIServer
}
$AllEvents | Out-GridView
Try something like this
$connectVIServer = @'
"Server", "User", "Password"
"10.10.10.10", "DOMAIN\VI-Admin1", "Pass1"
"20.20.20.20", "DOMAIN\VI-Admin2", "Pass2"
"99.99.99.99", "DOMAIN\VI-AdminX", "PassX"
'@
$connectVIServer | ConvertFrom-Csv -PipelineVariable row |
ForEach-Object -Process {
Write-Host "Connecting to '$($row.Server)'".
$paramConnectVIServer = @{
Server = $row.Server
User = $row.User
Password = $row.Password
}
Connect-VIServer @paramConnectVIServer
$paramGetVIEventPlus = @{
Recurse = $true
Entity = $_
Category = 'error', 'warning', 'user', 'info'
}
$AllEvents += Get-Cluster | Get-VIEventPlus @paramGetVIEventPlus
$paramDisconnectVIServer = @{
Server = $paramConnectVIServer.Server
Force = $true
}
Disconnect-VIServer @paramDisconnectVIServer
}
$AllEvents | Out-GridView
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Hi, @LucD many thanks for the update.
For the calculated property below, I wonder why it does not translate into meaningful text or strings although I have expanded it.
This is the snippet I am using:
$paramGetVIEventPlus = @{ Recurse = $true Entity = $_ Category = 'error', 'warning', 'user', 'info' FullMessage = $true Start = (Get-Date).AddDays(-1) Finish = (Get-Date) } Get-Cluster | Get-VIEventPlus @paramGetVIEventPlus | Select-Object IPAddress, CreatedTime, Username, @{ N = "DataCenter"; E = { $_.Datacenter } }, @{ N = "ComputeResource"; E = { $_.ComputeResource } }, @{ N = "Host"; E = { $_.Host } }, @{ N = "VM"; E = { $_.VM } }, FullFormattedMesage | Out-GridView
PowerCLI doesn't know how to show these objects, hence it shows the type of the object.
You want the Name property in those objects.
$paramGetVIEventPlus = @{ Recurse = $true Entity = $_ Category = 'error', 'warning', 'user', 'info' FullMessage = $true Start = (Get-Date).AddDays(-1) Finish = (Get-Date)
}
Get-Cluster |
Get-VIEventPlus @paramGetVIEventPlus |
Select-Object IPAddress,
CreatedTime,
Username,
@{ N = "DataCenter"; E = { $_.Datacenter.Name } },
@{ N = "ComputeResource"; E = { $_.ComputeResource.Name } },
@{ N = "Host"; E = { $_.Host.Name } },
@{ N = "VM"; E = { $_.VM.Name } },
FullFormattedMesage |
Out-GridView
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Yes, that works well.
One last thing, with the FullFormattedMesage property.
It does not show the value when I executed the above or the last code snippets like:
Get-Cluster |
Get-VIEventPlus @paramGetVIEventPlus |
Select-Object IPAddress,
CreatedTime,
Username,
@{ N = "DataCenter"; E = { $_.Datacenter.Name } },
@{ N = "ComputeResource"; E = { $_.ComputeResource.Name } },
@{ N = "Host"; E = { $_.Host.Name } },
@{ N = "VM"; E = { $_.VM.Name } },
@{ N = "FullFormattedMesage"; E = { $_.FullFormattedMesage.Name } } |
Out-GridView
but it shows fine when it is selected as *
Get-Cluster |
Get-VIEventPlus @paramGetVIEventPlus |
Select-Object IPAddress,
CreatedTime,
Username,
@{ N = "DataCenter"; E = { $_.Datacenter.Name } },
@{ N = "ComputeResource"; E = { $_.ComputeResource.Name } },
@{ N = "Host"; E = { $_.Host.Name } },
@{ N = "VM"; E = { $_.VM.Name } },
@{ N = "FullFormattedMesage"; E = { $_.FullFormattedMesage.Name } }, * |
Out-GridView
how to show the complete values for the FullFormattedMesage property?
Thank you.For the message there is no Name property, just $_.FullFormattedMessage should be sufficient.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Hi @LucD ,
Yes, I did that already, but somehow the FullFormattedMesage result is still not shown.
While select-object * shows everything including the FullFormattedMesage value.
Just noticed, there is a type in the property name.
It should be (double 's')
@{ N = "FullFormattedMesage"; E = { $_.FullFormattedMessage } }
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Yes, that works great,
Many thanks, @LucD for your great support as always.
