Hyper-V Server and a UPS
Microsoft’s Hyper-V Server 2008 R2 can be a great hypervisor choice for a small business with just one or two servers. In this environment though the common power protection scheme is going to be a single, direct-connected UPS with a USB signaling cable. In this scenario we need to be able to safely shutdown the hypervisor and guests before power gives out.
I claim no original thoughts here, but I did want to preserve a link to a good answer I found and have implemented. The original thread is here on the Technet Forums.
First create ups-shutdown.vbs and load it with:
set wmi = GetObject(“winmgmts:{impersonationLevel=impersonate,(Shutdown)}!\\.\root\cimv2″)
set batteryColl = wmi.ExecQuery(“select * from Win32_Battery”)
set osColl = wmi.ExecQuery(“select * from Win32_OperatingSystem”)while true
for each battery in batteryColl
battery.Refresh_
if battery.batteryStatus = 1 and battery.EstimatedChargeRemaining <= 40 then
for each os in osColl
os.Win32Shutdown 1
next
end if
next
wscript.Sleep 15000
wend
Schedule this to run at startup using the Task Scheduler. (Connect from another machine and set this up.)
Next create ups-monitor.ps1 and insert:
# Initialize Variables
# Shutdown threshold at 50% of remaining UPS capacity
$threshhold = 40
$interval = 60
$OnBattery = 0
$Event = 0$hostname = hostname
# Create SMTP client
$Server = “mail.xxxxxxxxxxxx.com”
$Port = 25
$Client = New-Object System.Net.Mail.SmtpClient $Server, $Port$Client.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials
$To = “admin@xxxxxxxxxxxx.com”
$From = “hyperv@yyyyyyyyyyyy.com”# Loop on Battery Query
while (1)
{
$bat = get-wmiobject -class CIM_Battery -namespace “root\CIMV2″
$batstatus = $bat.batterystatus
$batcapacity = $bat.estimatedchargeremaining
$timetoshutdown = $bat.estimatedruntime/2if ($batstatus -eq 1)
{
$Event = 1
$OnBattery = 1
# “On Battery”$Subject = “Utility Power Failure: {0} is running On UPS Battery” -f $hostname
$Body = “UPS at {0} % remaining capacity, approximately {1} minutes before {2} shutdown.” -f $batcapacity, $timetoshutdown, $hostnameif ($batcapacity -lt ($threshhold +5) )
{
$Body = “Shutdown imminent at {0} %, with ” -f $threshhold + $Body
}}
elseif (($batstatus -eq 2) -and ($OnBattery -eq 1))
{
$Event = 1
$OnBattery = 0
# “Power Restored”$Subject = “Utility Power Restored to {0}.” -f $hostname
$Body = “Battery at {0} % capacity. UPS charging… ” -f $batcapacity
}if ($Event -eq 1) # Create mail message
{
$Event = 0
$Message = New-Object System.Net.Mail.MailMessage $From, $To, $Subject, $Body
$Message.Priority = [System.Net.Mail.MailPriority]::High
try {
$Client.Send($Message)
# “Message sent successfully”
}
catch {
“Exception caught in UPS_Monitor.ps1″
}
}sleep $interval
}
Change the mail server, to and from address, and you’re in business.
Create ups-monitor.cmd with the following:
powershell -command c:\path\to\your\script\ups-monitor.ps1
Again using Task Scheduler, schedule ups-monitor.cmd to run at startup, and you’re set.
Make sure you have your VMs set to save at shutdown and autostart, and then go pull the plug on that UPS just to make sure things work to your liking.
Also from the above referenced thread, you can check the battery condition using powershell with this:
PS$ get-wmiobject -class CIM_Battery -namespace “root\CIMV2″
Have fun.


