Hi all
I have seen a few forums posts in regards to something similar to what I am trying to achieve, and although I understand getting replication status is somewhat difficult as there is no public API, I am hoping that something can be tweaked to get what I need via a script.
I am currently running the below which I found here:
Get-VIEvent -MaxSamples ([int]::MaxValue) | Where { $_.EventTypeId -match "hbr|rpo" } | Select CreatedTime, FullFormattedMessage, @{Name="VMName";Expression={$_.Vm.Name}} | export-csv -NoTypeInformation -Path ([Environment]::GetFolderPath("Desktop") + "\HBR-RPOEvents.csv")
However, that is returning everything under the FullFormattedMessage column. I'd like to filter that so it only contains "Virtual machine vSphere Replication RPO is violated by 1 minute(s)".
If possible, I would like to avoid the 1 minute part of the log though. The reason for this is that Alerts work well enough, and will email me when something is violated, but its constantly sending me the 1 minute messages, which subsequently clear under normal operation.
I'd ultimately like to get to a stage where I'm alerted if something is violated by more than 1 minute, and covers the last 24 hours.
Hope you can help.
Thanks.
Not tried that yet. Will have a look shortly.
However, this was much, much quicker:
Get-VIEventPlus -Start (Get-Date).adddays(-1) -MaxSamples ([int]::MaxValue) |
Where { $_.EventTypeId -match "hbr|rpo" -and $_.FullFormattedMessage -match "Virtual machine vSphere Replication RPO is violated" -and $_.FullFormattedMessage -notmatch "violated by 1 minute"} |
Select CreatedTime, FullFormattedMessage,
@{Name="VMName";Expression={$_.Vm.Name}} |
Export-Csv -NoTypeInformation -Path ([Environment]::GetFolderPath("Desktop") + "\HBR-RPOEvents_24hrs_eventplus.csv")
Will try the version that includes the sort-object and let you know how that goes.
Thanks for the help with this.
Worked an absolute treat Luc!
If I wanted to get this running from within the estate, and to send a daily email with the output forming part of the email to our operations and monitoring people, would the whole script have to look something like this:
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.Inventory.InventoryItemImpl[]]$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
}
}
Get-VIEventplus -Start (Get-Date).adddays(-1) -MaxSamples ([int]::MaxValue) |
Where { $_.EventTypeId -match "hbr|rpo" -and $_.FullFormattedMessage -match "Virtual machine vSphere Replication RPO is violated" -and $_.FullFormattedMessage -notmatch "violated by 1 minute"} |
Select CreatedTime, FullFormattedMessage,
@{Name="VMName";Expression={$_.Vm.Name}} |
Group-Object -Property VMName |
ForEach-Object -Process {
$_.Group | Sort-Object -Property CreatedTime -Descending |
select -First 1
} |
Export-Csv -NoTypeInformation -Path ([Environment]::GetFolderPath("Desktop") + "\HBR-RPOEvents_24hrs_eventplus_sort.csv")
Not having tried getting the output into an email yet, I going to presume its the last line following the pipe that would need to change somewhat?
You could do something like this.
To make the report in the email more colourful and nicely formatted, you can use HTML style elements.
For examples, have a look at Re: Datastore Capacity Load and Re: Formatting report
Where { $_.EventTypeId -match "hbr|rpo" -and $_.FullFormattedMessage -match "Virtual machine vSphere Replication RPO is violated" -and $_.FullFormattedMessage -notmatch "violated by 1 minute" } |
Select CreatedTime, FullFormattedMessage,
@{Name = "VMName"; Expression = { $_.Vm.Name } } |
Group-Object -Property VMName |
ForEach-Object -Process {
$_.Group | Sort-Object -Property CreatedTime -Descending |
select -First 1
}
$sMail = @{
To = 'you@domain'
From = 'me@domain'
Subject = 'Report'
SmtpServer = 'mail.domain'
BodyAsHtml = $true
Body = $report | ConvertTo-Html | Out-String
}
Send-MailMessage @sMail
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Hi LucD
I have been trying to test, but couldn't for various reasons.
Finally have it working though, and it did send a mail, but the body was empty. That is expected, as there were no entries that had violations above 1 minute last night though.
Is there anything that can be added to put a message in the email body that "no violations found" in the case that there is nothing returned please?
You could do something like this
Where { $_.EventTypeId -match "hbr|rpo" -and $_.FullFormattedMessage -match "Virtual machine vSphere Replication RPO is violated" -and $_.FullFormattedMessage -notmatch "violated by 1 minute" } |
Select CreatedTime, FullFormattedMessage,
@{Name = "VMName"; Expression = { $_.Vm.Name } } |
Group-Object -Property VMName |
ForEach-Object -Process {
$_.Group | Sort-Object -Property CreatedTime -Descending |
select -First 1
}
if(-not $report){
$report = 'no violations found'
}
$sMail = @{
To = 'you@domain'
From = 'me@domain'
Subject = 'Report'
SmtpServer = 'mail.domain'
BodyAsHtml = $true
Body = $report | ConvertTo-Html | Out-String
}
Send-MailMessage @sMail
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Email successfully received, with the below content:
* |
19 |
Looks like it does contain cells / borders though.
Then try like this
Where { $_.EventTypeId -match "hbr|rpo" -and $_.FullFormattedMessage -match "Virtual machine vSphere Replication RPO is violated" -and $_.FullFormattedMessage -notmatch "violated by 1 minute" } |
Select CreatedTime, FullFormattedMessage,
@{Name = "VMName"; Expression = { $_.Vm.Name } } |
Group-Object -Property VMName |
ForEach-Object -Process {
$_.Group | Sort-Object -Property CreatedTime -Descending |
select -First 1
}
if(-not $report){
$body = ConvertTo-Html -Body 'no violations found' | Out-String
}
else{
$body = $report | ConvertTo-Html | Out-String
}
$sMail = @{
To = 'you@domain'
From = 'me@domain'
Subject = 'Report'
SmtpServer = 'mail.domain'
BodyAsHtml = $true
Body = $body
}
Send-MailMessage @sMail
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Amazing as ever!
Thanks LucD.
Hi LucD
Sorry to drag this one up again. Is there an easy change to the script that will alter the subject of the e-mail if there are no violations when none are found, as opposed to the subject hard coded as 'Report' please?
Thanks
No problem.
You can use the same test we used for the Body.
The mail part could then be
$body = ConvertTo-Html -Body 'no violations found' | Out-String
$subject = 'No violations found'
}
else{
$body = $report | ConvertTo-Html | Out-String
$subject = 'Report'
}
$sMail = @{
To = 'you@domain'
From = 'me@domain'
Subject = $subject
SmtpServer = 'mail.domain'
BodyAsHtml = $true
Body = $body
}
Send-MailMessage @sMail
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference