Tool updated June 17, 2017 – V3.0 [If any of the virtual machine is in Warning or Critical states, the replication will be resumed automatically without administrator intervention to restore the replication, as well as adding Hyper-V Replica Broker in a Cluster scenario].

A hyper-V copy can be your lifesaver if a disaster happens, and at the same time it can be your enemy if you don’t follow it.

If you have used a Hyper-V copy (of course you did;)), you know the copy of the status column in the Hyper-V Manager console. This is the part of the interface where you can see the status of the copy: Normal, Warning or Critical. A simple interpretation of these states is as follows:

  • Normal: No worries, everything is fine! A virtual machine with a status of Normal if any of the following occurs:
    • Less than 20% of replication experiments have been missed.
    • Average delay. This is important because Hyper-V Copy wants to copy the Hyper-V Copy Log File (HRL) every 30 seconds, 5 minutes, or 15 minutes. This depends on the set replication rate.
  • WarningA: There have been some problems, but Hyper-V will try to fix them automatically. The virtual machine has a warning state if any of the following occurs:
    • The original copy is not copied or synchronized.
    • More than 20% of replication cycles have been skipped during the current follow-up interval.
    • An hour or more has elapsed since the last transmission copy was sent / received.
    • Replication of the source virtual machine is in a paused state.
    • Fault tolerance has been initiated, but reverse replication has not been initiated.
  • CriticalA: Sorry, things have passed points where Hyper-V can fix them for you, and that’s why you need to address it. A virtual machine has a critical state if one of the following occurs:
    • The primary host of the source is unable to send Hyper-V traffic to the replica host, this may be a network or firewall issue.
    • Replication is aborted on the primary or copy host.

One of the problems is that things can go really bad if the Hyper-V copy is in critical condition for a long time (the (AVHD / AVHDX) partition grows and can cause a big mess on the primary server, and next you want to know when things go wrong right? because if something goes wrong in the environment that causes virtual machines to go into a warning or critical state – I want to know! And I want to fix it so it doesn’t happen again! I don’t want to think that life is good when I really have a problem to fix

Additional note: Hyper-V Replica creates an AVHDX to handle the original replication of the virtual machine (i.e., getting the first copy of the virtual machine over the replica host). Hyper-V Replica combines this disk after it has successfully made a complete copy of the virtual machine, the virtual hard disk (which may take a while).

So for this reason, I’ve created a great PowerShell script that sends an email to a Hyper-V administrator when something goes wrong with a copy of Hyper-V in the nice HTML format of the control panel.

This script checks the first Hyper-V Replica TCP listener on Port 80 because Hyper-V Replica requires HTTP and HTTPS rules to be enabled in Windows Firewall and then sends an e-mail Replication State, Replication Mode, Replica Target frequency (30 seconds, 5 min or 15 min) and how far the virtual copy replica is from the primary virtual machine (Delta per minute), then the last replication time and the number of unanswered copies used by the Virtual Machines in alerts and Critical Modes only to the email address specified in HTML table format. This can, of course, be used in conjunction with a task scheduler to receive notification when something out of the ordinary is regularly monitored for monitoring purposes (see End of this article for task automation).

I want to mention that this tool was created using SAPIEN PowerShell Studio 2015 which is a great support when creating advanced scripts or making GUI tools like the next tool Moment.

Get-HyperVReplicaHealthV1.0-04

How to use:

  • Use –PrimHyperV01 parameter to change the primary Hyper-V host and obtain information about all primary virtual machines. If not, it uses the Hyper-V host that is configured in the script by default.
  • Use –RepHyperV02 parameter to change the copy of the Hyper-V host and obtain information about all primary virtual machines. If not, it uses the Hyper-V host that is configured in the script by default.
  • Use –ExtHyperV03 parameter to check the extended Hyper-V Replica host and get information about all primary virtual machines. If not, it only uses primary and replica Hyper-V hosts.
  • You can run the script on a remote management machine loaded as recommended with the Hyper-V PowerShell module, or you can run it directly on a Hyper-V host that I do not recommend.

Examples:

Get-HyperVReplicaHealthV1.0-05

This example first checks the HTTP connection to the primary and Replica Hyper-V servers. If both nodes are reachable, it will search for primary virtual machines that are in alert and critical state and send you a notification.

Get-HyperVReplicaHealthV1.0-06

This example first checks the HTTP connection to the primary, replica, and extended copy Hyper-V servers. If all nodes are reachable, it will search for primary virtual machines that are in alert and critical state and send you a notification.

<#
    .SYNOPSIS
    Advanced Hyper-V Replica Monitoring tool.

    .DESCRIPTION
    Advanced Hyper-V Replica Monitoring tool including email Alerts.

    .NOTES
    ===========================================================================
    Created with : SAPIEN Technologies, Inc., PowerShell Studio 2015 v4.2.82
    File Name    : Get-HyperVReplicaHealth.ps1
    Author       : Charbel Nemnom
    Version      : 2.0
    Date created : 07.April.2015
    Last modified: 17.June.2016
    Requires     : PowerShell Version 4.0 or above
    OS           : Windows Server 2012, 2012 R2 or 2016 Hyper-V
    Module       : Hyper-V-PowerShell
    ===========================================================================

    .LINK
    To provide feedback or for further assistance please visit:
    
Cover Page
.EXAMPLE .Get-HyperVReplicaHealth.ps1 -PrimHyperV01 <PrimaryHost> -RepHyperV02 <ReplicaHost> This example will check first the HTTP connectivity to the Primary and Replica Hyper-V server, If both nodes are reachable, then it will look for primary Virtual Machines that are in Warning and Critical state and send you an alert. If any of the virtual machine is in Warning or Critical states, The replication will be resumed automatically without administrator intervention to restore the replication. .EXAMPLE .Get-HyperVReplicaHealth.ps1 -PrimHyperV01 <PrimaryHost> -RepHyperV02 <ReplicaHost> -ExtHyperV03 <ExtendedReplicaHost> This example will check first the HTTP connectivity to the Primary, Replica and Extended Replica Hyper-V Hosts, If all nodes are reachable, then it will look for primary Virtual Machines that are in Warning and Critical state and send you an alert. If any of the virtual machine is in Warning or Critical states, The replication will be resumed automatically without administrator intervention to restore the replication. #> [CmdletBinding()] param ( [Parameter(Position = 0, HelpMessage = 'Primary Hyper-V Server')] [Alias('PrimHV')] [String]$PrimHyperV01 = 'NINJA-HV01.VIRT.LAB', [Parameter(HelpMessage = 'Replica Hyper-V Server')] [Alias('RepHV')] [String]$RepHyperV02 = 'NINJA-HV02.VIRT.LAB', [Parameter(HelpMessage = 'Extended Hyper-V Replica Server')] [Alias('ExtHV')] [String]$ExtHyperV03 ) # Variables $Filedate = Get-date $report = $null $FromEmail = "[email protected]" $ToEmail1 = "[email protected]" $ToEmail2 = "[email protected]" $email = new-object Net.Mail.MailMessage $email.From = new-object Net.Mail.MailAddress($FromEmail) $email.Priority = [System.Net.Mail.MailPriority]::High $email.IsBodyHtml = $true $email.Body = $report $email.To.Add($ToEmail1) $email.To.Add($ToEmail2) $tableColor = "WhiteSmoke" $errorColor = "Red" $warningColor = "Yellow" If ($ExtHyperV03) { $HyperVHosts = "$PrimHyperV01", "$RepHyperV02", "$ExtHyperV03" } Else { $HyperVHosts = "$PrimHyperV01", "$RepHyperV02" } # Establish Connection to SMTP server $smtpServer = "smtp.domain.com" $smtpCreds = new-object Net.NetworkCredential("username", "PassW0rd") $smtp = new-object Net.Mail.SmtpClient($smtpServer) $smtp.UseDefaultCredentials = $false $smtp.Credentials = $smtpCreds # HTML Style Definition $report += "<!DOCTYPE html PUBLIC`"-//W3C//DTD XHTML 1.0 Strict//EN`" `"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd`">" $report += "<html xmlns=`"http://www.w3.org/1999/xhtml`"><body>" $report += "<style>" $report += "TABLE{border-width:2px;border-style: solid;border-color: #C0C0C0 ;border-collapse: collapse;width: 100%}" $report += "TH{border-width: 2px;padding: 0px;border-style: solid;border-color: #C0C0C0 ;text-align: left}" $report += "TD{border-width: 2px;padding: 0px;border-style: solid;border-color: #C0C0C0 ;text-align: left}" $report += "TD{border-width: 2px;padding: 0px;border-style: solid;border-color: #C0C0C0 ;text-align: left}" $report += "H1{font-family:Calibri;}" $report += "H2{font-family:Calibri;}" $report += "H3{font-family:Calibri;}" $report += "Body{font-family:Calibri;}" $report += "</style>" $report += "<center><p style=""font-size:12px;color:#BDBDBD"">Get-HyperVReplicaHealth - ScriptVersion: 1.0 | Created By: Charbel Nemnom - Hyper-V MVP | Feedback: https://charbelnemnom.com</p></center>" # Test Primary Hyper-V Host on Port 80, if not reachable then send email and terminate! If ($PrimHyperV01) { Write-Verbose "Checking $PrimHyperV01" $TestHVNode1HTTP = 1..3 | % { Test-NetConnection -ComputerName $PrimHyperV01 -Port 80 } If ($TestHVNode1HTTP.TcpTestSucceeded[2] -eq $false) { Write-Verbose "$PrimHyperV01 is Not Reachable" $email.Subject = "$PrimHyperV01 is not Reachable! $($filedate)" $report += "<B><p style=""color:#ff0000"">Error Hyper-V Replica HTTP Listener on $PrimHyperV01!</B></p> <br> <br>" Write-Verbose "Finalizing Report" $report += "</body></html>" Write-Verbose "Sending e-mail" $email.body = $report $smtp.Send($email) Break } } # Test Replica Hyper-V Host on Port 80, if not reachable then send email and terminate! If ($RepHyperV02) { Write-Verbose "Checking $RepHyperV02" $TestHVNode2HTTP = 1..3 | % { Test-NetConnection -ComputerName $RepHyperV02 -Port 80 } If ($TestHVNode2HTTP.TcpTestSucceeded[2] -eq $false) { Write-Verbose "$RepHyperV02 is Not Reachable" $email.Subject = "$RepHyperV02 is not Reachable! $($filedate)" $report += "<B><p style=""color:#ff0000"">Error Hyper-V Replica HTTP Listener on $RepHyperV02!</B></p> <br> <br>" Write-Verbose "Finalizing Report" $report += "</body></html>" Write-Verbose "Sending e-mail" $email.body = $report $smtp.Send($email) Break } } # Test Extended Hyper-V Replica Host on Port 80, if not reachable then send email and terminate! If ($ExtHyperV03) { Write-Verbose "Checking $ExtHyperV03" $TestHVNode3HTTP = 1..3 | % { Test-NetConnection -ComputerName $ExtHyperV03 -Port 80 } If ($TestHVNode3HTTP.TcpTestSucceeded[2] -eq $false) { Write-Verbose "$ExtHyperV03 is Not Reachable" $email.Subject = "$ExtHyperV03 is not Reachable! $($filedate)" $report += "<B><p style=""color:#ff0000"">Error Hyper-V Replica HTTP Listener on $ExtHyperV03!</B></p> <br> <br>" Write-Verbose "Finalizing Report" $report += "</body></html>" Write-Verbose "Sending e-mail" $email.body = $report $smtp.Send($email) Break } } # Check VM Replication in Warning State If ($ExtHyperV03) { $WarningVMs = Get-VM -computername $PrimHyperV01, $RepHyperV02, $ExtHyperV03 | ? { $_.ReplicationMode -eq "Primary" -and $_.ReplicationHealth -eq "Warning" } | select ReplicationHealth } Else { $WarningVMs = Get-VM -computername $PrimHyperV01, $RepHyperV02 | ? { $_.ReplicationMode -eq "Primary" -and $_.ReplicationHealth -eq "Warning" } | select ReplicationHealth } # Check VM Replication in critical State If ($ExtHyperV03) { $CriticalVMs = Get-VM -computername $PrimHyperV01, $RepHyperV02, $ExtHyperV03 | ? { $_.ReplicationMode -eq "Primary" -and $_.ReplicationHealth -eq "Critical" } | select ReplicationHealth } Else { $CriticalVMs = Get-VM -computername $PrimHyperV01, $RepHyperV02 | ? { $_.ReplicationMode -eq "Primary" -and $_.ReplicationHealth -eq "Critical" } | select ReplicationHealth } If ($WarningVMs -match "Warning") { Write-Verbose "Warning Replica VMs Found" $email.Subject = "Virtual Machines Replication in Warning State! $($filedate)" $report += "<style>TH{background-color:Indigo}TR{background-color:$($warningColor)}</style>" # Get VM Replication Warning State (Primary, Replica and Extended Hyper-V Replica hosts) $report += "<B>Virtual Machine Warning Replication State!</B> <br> <br>" If ($ExtHyperV03) { # Resume VM Replication Write-Verbose "Resume VM Warning Replication..." Get-VM -ComputerName $PrimHyperV01, $RepHyperV02, $ExtHyperV03 | ? { $_.ReplicationHealth -eq "Warning" -and $_.ReplicationState -ne "Replicating"} | Resume-VMReplication -Resynchronize $report += "Virtual Machine Replication Health: <br>" + ((Get-VM -computername $PrimHyperV01, $RepHyperV02, $ExtHyperV03 | ? { $_.ReplicationMode -eq "Primary" -and $_.ReplicationHealth -eq "Warning" } | Get-VMReplication | ` Select-Object @{ Expression = { $_.Name }; Label = "Name" }, ` @{ Expression = { $_.ReplicationState }; Label = "Replication State" }, ` @{ Expression = { $_.ReplicationMode }; Label = "Replication Mode" }, ` @{ Expression = { $_.ReplicationHealth }; Label = "Replication Health" }, ` @{ Expression = { "{0:0.0}" -f ($_.FrequencySec / 60) }; Label = "Target Freq (min)" }, ` @{ Expression = { "{0:N0}" -f (($Filedate) - ($_.Lastreplicationtime)).TotalMinutes }; Label = "Delta (min)" }, ` @{ Expression = { $_.ComputerName }; Label = "Hyper-V Host" } ` | ConvertTo-HTML -Fragment) ` | %{ if ($_.Contains("<td>Replicating</td><td>Normal</td>")) { $_.Replace("<tr><td>", "<tr style=`"background-color:$($tableColor)`"><td>") } else { $_ } }) ` + " <br>" } Else { # Resume VM Replication Write-Verbose "Resume VM Warning Replication..." Get-VM -ComputerName $PrimHyperV01, $RepHyperV02 | ? { $_.ReplicationHealth -eq "Warning" -and $_.ReplicationState -ne "Replicating"} | Resume-VMReplication -Resynchronize # Get VM Replication Warning State (Primary, and Replica Hyper-V hosts) $report += "Virtual Machine Replication Health: <br>" + ((Get-VM -computername $PrimHyperV01, $RepHyperV02 | ? { $_.ReplicationMode -eq "Primary" -and $_.ReplicationHealth -eq "Warning" } | Get-VMReplication | ` Select-Object @{ Expression = { $_.Name }; Label = "Name" }, ` @{ Expression = { $_.ReplicationState }; Label = "Replication State" }, ` @{ Expression = { $_.ReplicationMode }; Label = "Replication Mode" }, ` @{ Expression = { $_.ReplicationHealth }; Label = "Replication Health" }, ` @{ Expression = { "{0:0.0}" -f ($_.FrequencySec / 60) }; Label = "Target Freq (min)" }, ` @{ Expression = { "{0:N0}" -f (($Filedate) - ($_.Lastreplicationtime)).TotalMinutes }; Label = "Delta (min)" }, ` @{ Expression = { $_.ComputerName }; Label = "Hyper-V Host" } ` | ConvertTo-HTML -Fragment) ` | %{ if ($_.Contains("<td>Replicating</td><td>Normal</td>")) { $_.Replace("<tr><td>", "<tr style=`"background-color:$($tableColor)`"><td>") } else { $_ } }) ` + " <br>" } # Measure VM Replication Warning State If ($ExtHyperV03) { $report += "Measure Virtual Machine Replication Health: <br>" + ((Get-VM -computername $PrimHyperV01, $RepHyperV02, $ExtHyperV03 | ? { $_.ReplicationMode -eq "Primary" -and $_.ReplicationHealth -eq "Warning" } | Measure-VMReplication | ` Select-Object @{ Expression = { $_.Name }; Label = "Name" }, ` @{ Expression = { $_.LReplTime }; Label = "Last Replication Time" }, ` @{ Expression = { $_.AvgLatency }; Label = "Avg Latency" }, ` @{ Expression = { $_.AvgReplSize }; Label = "Avg Repl Size" }, ` @{ Expression = { $_.MissedReplicationCount }; Label = "Missed Repl Count" } ` | ConvertTo-HTML -Fragment) ` | %{ if ($_.Contains("<td>Replicating</td><td>Normal</td>")) { $_.Replace("<tr><td>", "<tr style=`"background-color:$($tableColor)`"><td>") } else { $_ } }) ` + " <br> " } Else { $report += "Measure Virtual Machine Replication Health: <br>" + ((Get-VM -computername $PrimHyperV01, $RepHyperV02 | ? { $_.ReplicationMode -eq "Primary" -and $_.ReplicationHealth -eq "Warning" } | Measure-VMReplication | ` Select-Object @{ Expression = { $_.Name }; Label = "Name" }, ` @{ Expression = { $_.LReplTime }; Label = "Last Replication Time" }, ` @{ Expression = { $_.AvgLatency }; Label = "Avg Latency" }, ` @{ Expression = { $_.AvgReplSize }; Label = "Avg Repl Size" }, ` @{ Expression = { $_.MissedReplicationCount }; Label = "Missed Repl Count" } ` | ConvertTo-HTML -Fragment) ` | %{ if ($_.Contains("<td>Replicating</td><td>Normal</td>")) { $_.Replace("<tr><td>", "<tr style=`"background-color:$($tableColor)`"><td>") } else { $_ } }) ` + " <br> " } # Get Hyper-V Replica Warning Log $report += "<style>TH{background-color:$($warningColor)}TR{background-color:$($tableColor)}</style>" $report += "<B>Hyper-V Replica Warnings Event Log</B> <br> <br>" Foreach ($HyperVHost in $HyperVHosts) { $report += "Warnings $HyperVHost : <br>" + ((Get-WinEvent -ComputerName $HyperVHost -FilterHashTable @{ LogName = "Microsoft-Windows-Hyper-V-VMMS-Admin"; StartTime = ($Filedate).AddDays(-1); Level = 3 }) | ` Select-Object @{ Expression = { $_.ID }; Label = "ID" }, ` @{ Expression = { $_.ProviderName }; Label = "Source" }, ` @{ Expression = { $_.Message }; Label = "Message" } ` | ConvertTo-HTML -Fragment) ` + " <br>" } } If ($CriticalVMs -match "Critical") { Write-Verbose "Critical Replica VMs Found" $email.Subject = "Virtual Machines Replication in Critical State! $($filedate)" $report += "<style>TH{background-color:Indigo}TR{background-color:$($errorColor)}</style>" # Get VM Replication Critical State (Primary, Replica and Extended Hyper-V Replica hosts) $report += "<B>Virtual Machine Critical Replication State!</B> <br> <br>" If ($ExtHyperV03) { # Resume VM Replication Write-Verbose "Resume VM Critical Replication..." Get-VM -ComputerName $PrimHyperV01, $RepHyperV02, $ExtHyperV03 | ? { $_.ReplicationHealth -eq "Critical" -and $_.ReplicationState -ne "Resynchronizing" } | Resume-VMReplication -Resynchronize $report += "Virtual Machine Replication Health: <br>" + ((Get-VM -computername $PrimHyperV01, $RepHyperV02, $ExtHyperV03 | ? { $_.ReplicationMode -eq "Primary" -and $_.ReplicationHealth -eq "Critical" } | Get-VMReplication | ` Select-Object @{ Expression = { $_.Name }; Label = "Name" }, ` @{ Expression = { $_.ReplicationState }; Label = "Replication State" }, ` @{ Expression = { $_.ReplicationMode }; Label = "Replication Mode" }, ` @{ Expression = { $_.ReplicationHealth }; Label = "Replication Health" }, ` @{ Expression = { "{0:0.0}" -f ($_.FrequencySec / 60) }; Label = "Target Freq (min)" }, ` @{ Expression = { "{0:N0}" -f (($Filedate) - ($_.Lastreplicationtime)).TotalMinutes }; Label = "Delta (min)" }, ` @{ Expression = { $_.ComputerName }; Label = "Hyper-V Host" } ` | ConvertTo-HTML -Fragment) ` | %{ if ($_.Contains("<td>Replicating</td><td>Normal</td>")) { $_.Replace("<tr><td>", "<tr style=`"background-color:$($tableColor)`"><td>") } else { $_ } }) ` + " <br>" } Else { # Resume VM Replication Write-Verbose "Resume VM Critical Replication..." Get-VM -ComputerName $PrimHyperV01, $RepHyperV02 | ? { $_.ReplicationHealth -eq "Critical" -and $_.ReplicationState -ne "Resynchronizing" } | Resume-VMReplication -Resynchronize # Get VM Replication Critical State (Primary, and Replica Hyper-V hosts) $report += "Virtual Machine Replication Health: <br>" + ((Get-VM -computername $PrimHyperV01, $RepHyperV02 | ? { $_.ReplicationMode -eq "Primary" -and $_.ReplicationHealth -eq "Critical" } | Get-VMReplication | ` Select-Object @{ Expression = { $_.Name }; Label = "Name" }, ` @{ Expression = { $_.ReplicationState }; Label = "Replication State" }, ` @{ Expression = { $_.ReplicationMode }; Label = "Replication Mode" }, ` @{ Expression = { $_.ReplicationHealth }; Label = "Replication Health" }, ` @{ Expression = { "{0:0.0}" -f ($_.FrequencySec / 60) }; Label = "Target Freq (min)" }, ` @{ Expression = { "{0:N0}" -f (($Filedate) - ($_.Lastreplicationtime)).TotalMinutes }; Label = "Delta (min)" }, ` @{ Expression = { $_.ComputerName }; Label = "Hyper-V Host" } ` | ConvertTo-HTML -Fragment) ` | %{ if ($_.Contains("<td>Replicating</td><td>Normal</td>")) { $_.Replace("<tr><td>", "<tr style=`"background-color:$($tableColor)`"><td>") } else { $_ } }) ` + " <br>" } # Measure VM Replication Critical State If ($ExtHyperV03) { $report += "Measure Virtual Machine Replication Health: <br>" + ((Get-VM -computername $PrimHyperV01, $RepHyperV02, $ExtHyperV03 | ? { $_.ReplicationMode -eq "Primary" -and $_.ReplicationHealth -eq "Critical" } | Measure-VMReplication | ` Select-Object @{ Expression = { $_.Name }; Label = "Name" }, ` @{ Expression = { $_.LReplTime }; Label = "Last Replication Time" }, ` @{ Expression = { $_.AvgLatency }; Label = "Avg Latency" }, ` @{ Expression = { $_.AvgReplSize }; Label = "Avg Repl Size" }, ` @{ Expression = { $_.MissedReplicationCount }; Label = "Missed Repl Count" } ` | ConvertTo-HTML -Fragment) ` | %{ if ($_.Contains("<td>Replicating</td><td>Normal</td>")) { $_.Replace("<tr><td>", "<tr style=`"background-color:$($tableColor)`"><td>") } else { $_ } }) ` + " <br> " } Else { $report += "Measure Virtual Machine Replication Health: <br>" + ((Get-VM -computername $PrimHyperV01, $RepHyperV02 | ? { $_.ReplicationMode -eq "Primary" -and $_.ReplicationHealth -eq "Critical" } | Measure-VMReplication | ` Select-Object @{ Expression = { $_.Name }; Label = "Name" }, ` @{ Expression = { $_.LReplTime }; Label = "Last Replication Time" }, ` @{ Expression = { $_.AvgLatency }; Label = "Avg Latency" }, ` @{ Expression = { $_.AvgReplSize }; Label = "Avg Repl Size" }, ` @{ Expression = { $_.MissedReplicationCount }; Label = "Missed Repl Count" } ` | ConvertTo-HTML -Fragment) ` | %{ if ($_.Contains("<td>Replicating</td><td>Normal</td>")) { $_.Replace("<tr><td>", "<tr style=`"background-color:$($tableColor)`"><td>") } else { $_ } }) ` + " <br> " } # Get Hyper-V Replica Critical Log $report += "<style>TH{background-color:$($errorColor)}TR{background-color:$($tableColor)}</style>" $report += "<B>Hyper-V Replica Critical Event Log</B> <br> <br>" Foreach ($HyperVHost in $HyperVHosts) { $report += "Errors $HyperVHost : <br>" + ((Get-WinEvent -ComputerName $HyperVHost -FilterHashTable @{ LogName = "Microsoft-Windows-Hyper-V-VMMS-Admin"; StartTime = ($Filedate).AddDays(-1); Level = 2 }) | ` Select-Object @{ Expression = { $_.ID }; Label = "ID" }, ` @{ Expression = { $_.ProviderName }; Label = "Source" }, ` @{ Expression = { $_.Message }; Label = "Message" } ` | ConvertTo-HTML -Fragment) ` + " <br>" } } If ($WarningVMs -and $CriticalVMs) { $email.Subject = "Virtual Machines Replication in Warning & Critical State! $($filedate)" Write-Verbose "Finalizing Report" $report += "</body></html>" Write-Verbose "Sending e-mail" $email.body = $report $smtp.Send($email) } Elseif ($WarningVMs -or $CriticalVMs) { Write-Verbose "Finalizing Report" $report += "</body></html>" Write-Verbose "Sending e-mail" $email.body = $report $smtp.Send($email) }

Sample output:

The node is not an available message!

Get-HyperVReplicaHealthV1.0-01

Warning status message!

Get-HyperVReplicaHealthV1.0-02

Critical status notification!

Get-HyperVReplicaHealthV1.0-03

Last but not least, you can automate Get HyperVReplicaHealth the script uses the Task Scheduler every hour and notifies you if something goes wrong with your Hyper-V copy. You can do this using Register Schedule cmdlet. Here is an example of monitoring the Hyper-V Replica infrastructure every hour:

$Cred = Get-Credential "VIRTSuperVirt"
$trigger = New-ScheduledTaskTrigger -Once -At (Get-Date) -RepetitionInterval (New-TimeSpan -Hours 1) -RepetitionDuration ([TimeSpan]::MaxValue)
$option = New-ScheduledJobOption -RunElevated
Register-ScheduledJob -Name HyperVReplicaMonitor -Trigger $trigger -FilePath "C:UsersSuperVirtDesktopPoSh ScriptsGet-HyperVReplicaHealth.ps1" -ScheduledJobOption $option -Credential $cred

This is version 3.0, do you have any other scenarios? Leave your Feedback below.

You can download a copy of this tool at TechNet Gallery GitHub here.

Until then … Enjoy your day!

Cheers,
/ Charbel

LEAVE A REPLY

Please enter your comment!
Please enter your name here