5

This is related to a specific issue, but I think it is an "interesting" question for general use: In Windows (specifically 2k8 server, for me) you have a task that is triggered by an event (specifically, the UPS goes on battery because power failed) with a delay (the battery will last at least 15 minutes) and then perform some action (specifically, shutdown /s /t 60 /d U:6:12). But there is some other event (specifically, the UPS goes OFF battery because power has been restored) that should then block the first task from happening (specifically, don't shut down) IF it happens during the delay.

I started thinking about this because the software for managing server shutdown that came with my UPS is pure... oh, I'm supposed to be polite here aren't I? ... um... very very not good. So I was thinking about how to provide the standard shutdown before battery runs out functionality without it. Normally, the system would get a message from the UPS that the battery was about to run out, then shut down. This UPS does NOT send that message. It sends "I'm on Battery", "I'm on AC" and that. is. it. No message for "I'm about to die".

But I think that could be a useful trick for other situations as well. Anytime there is something that you want to do after something has been happening for a while without recovery. E.g. if you can't communicate with a remote PC for some period of time, send a message to the smart power strip to power cycle it... But not if the communication is restored. Or if you haven't been able to get data from one source for some period of time, switch to a backup data source... But not if the primary source starts responding.

Can it be done? I don't see a way...

HopelessN00b
  • 53,385
  • 32
  • 133
  • 208
James Newton
  • 164
  • 9
  • 1
    The linux tools for handling a ups are quite good. If you have any linux systems you might want to have them deal with the ups and tell the windows machines when to shutdown. – Grant Dec 15 '14 at 20:31
  • 1
    There is also other alternative UPS software for Windows -- I've personally used Apcupsd in the past (with a UPS that had also sh- I mean "very very not good" software) – gregmac Dec 15 '14 at 22:31

2 Answers2

6

This is a neat idea. I would write this for you in Powershell or C#, in a few hours, for a very modest fee. ;)

Just kidding. How about this...

Use Task Scheduler to create two tasks. Each task will be triggered on an Event Log event. Task number one will trigger based on the "AC power is gone" event, and it would execute an action like shutdown /s /t 1200 to shutdown the system with a delay of 1200 seconds. Then the second task will trigger based on the event log event for "AC power has been restored." The second task will execute a shutdown /a to abort the pending shutdown.

I think anything more advanced than that will need to be scripted.


shutdown

Ryan Ries
  • 55,011
  • 9
  • 138
  • 197
  • Yeah, that's exactly what I did. With NO delay set on the task trigger, and the delay coming from the /t. But 1. shutdown /t can only be a maximum of 600 seconds and the UPS will probably go for a half hour and 2. It seems like there would be other instances where the delay setting on the task trigger would be useful. – James Newton Dec 15 '14 at 23:46
  • That's interesting, your shutdown is working nicely with more than 600. On my 2k8 server, shutdown/? gives: `/t xxx Set the time-out period before shutdown to xxx seconds. The valid range is 0-600, with a default of 30. Using /t xxx implies the /f option.` And if I try shutdown /r /t 601 it just shows the help again. /t 600 is the largest value that actually works. – James Newton Dec 17 '14 at 16:42
3

Extending on Ryan's approach using 2 tasks, one triggered by "Power Gone", and an "abort" button task, triggered by a "Power Restore" event

In case you need to do something more generic (not every executable has an abort switch like shutdown), and want to maintain a few-minute buffer before you start sending emails to management, wiping disks or self-destruct the datacenter (or whatever else you want to automate in an emergency), you could make the first one stall/wait for a while, and have the second task stop the first one if triggered:

PowerGone task:

Send-MailMessage -To "james@company.tld" -Body "Self-destruction sequence initiated, T-10m"
# We can still abort this task
Start-Sleep -Seconds 600
Send-MailMessage -To "everyone@company.tld" -Subject "Notice of termination..."
Start-Implosion -Force

PowerBack task:

$TaskScheduler = New-Object -ComObject Schedule.Service
$TaskScheduler.Connect("localhost")

$TargetTask = $TaskScheduler.GetFolder('\').GetTask('PowerGone')
$TargetTask.Stop()
Mathias R. Jessen
  • 24,907
  • 4
  • 62
  • 95
  • I'm not familiar with the environment you are using here. Are these Powershell? How does the first task get the name "PowerGone" so the second task can find it? (that's probably a stupid question if one has PowerShell experience... I don't! LOL) – James Newton Dec 15 '14 at 23:48
  • 1
    Sorry, these are powershell snippets, you would name the actual tasks (created in task scheduler) "PowerGone" and "PowerRestored" or something similar. – Mathias R. Jessen Dec 16 '14 at 08:19
  • Ah... so "PowerGone" is the name of the task! Makes perfect sense now. Thanks. – James Newton Dec 17 '14 at 16:35