I set up Hyper-V replica between two clusters in two offices, and needed a way of keeping track of replica health. I used a PowerShell script running from a utility server on a scheduled task to accomplish this.
This script runs a “get-vmreplication” command on each cluster node, and sends an email if any is found in warning or critical state.
One issue I needed to solve was the permissions required to run this from a utility server. I’m sure there are many other (and better) ways to accomplish this such as group managed service accounts, but there are certain limitations in my environment.
First I created an account in AD to act as a service account, as a standard user. I used the “ConvertFrom-SecureString” cmdlet as demonstrated in this article, as the SYSTEM account on my utility server, to produce a file for building a credential object in my PowerShell script. To run this as SYSTEM I used “psexec -s -i powershell.exe”.
Then I created a scheduled task, set to run as SYSTEM when not logged on, at 12 hour intervals, with the action of running the script below:
$password = Get-Content C:\scripts\MaintenanceChecks\SecureString.txt | ConvertTo-SecureString $Credential = New-Object System.Management.Automation.PSCredential("svc.clusterhealth@domain.com",$password) $Servers = @("ClusterHost1","ClusterHost2","ClusterHost3","ClusterHost4") Foreach ($server in $Servers) { Invoke-Command -credential $credential -computername $server -scriptblock { $resultsWarn = get-vmreplication | where-object {$_.Health -like "Warning"} if ($resultsWarn) { $smtpServer = "relay.domain.com" $port = "25" $message = New-Object System.Net.Mail.MailMessage $message.From = "fromaddress@domain.com" $message.Sender = "fromaddress@domain.com" $message.To.Add( "toaddress@domain.com" ) $message.Subject = "Replication Health Warning - $($Using:server)" $message.IsBodyHtml = $true $message.Body = "Replication health was found to be in warning state for the following VMs: $($resultsWarn.Name)" $Client = New-Object System.Net.Mail.SmtpClient( $smtpServer , $port ) $Client.Send( $message ) } $resultsCrit = get-vmreplication | where-object {$_.Health -like "Critical"} if ($resultsCrit) { $smtpServer = "relay.domain.com" $port = "25" $message = New-Object System.Net.Mail.MailMessage $message.From = "fromaddress@domain.com" $message.Sender = "fromaddress@domain.com" $message.To.Add( "toaddress@domain.com" ) $message.Subject = "Replication Health Critical - $($Using:server)" $message.IsBodyHtml = $true $message.Body = "Replication health was found to be in CRITICAL state for the following VMs: $($resultsCrit.Name)" $Client = New-Object System.Net.Mail.SmtpClient( $smtpServer , $port ) $Client.Send( $message ) } } } |