System shutdowns

Shutting down a system often involves either rebooting, powering off, or performing some other action like hibernation and/or suspension.

Supporting shutdown options

(This section was marked with a note (which might be old now) stating “This section could be improved a bit”.

The specific command typically used to shut down the system may vary between different systems. The options used by a specific program, such as “ shutdown ”, may vary (being different between BSD and Linux and both of those being different from Windows Vista). In general, see if any of the following commands exist: shutdown, reboot, and/or halt. Also, run alias (in either Unix or JP Software) to see if there is an alias using any of those names, or an alias with any name similar to rebooting or shutting down a program, such as “ die ” which ends up terminating all running software due to the shutdown occurring.

Of course, computers have typically needed external power supplied (unless they have an internal source of power). The section about electrical power might provide some helpful details.

Some software which may shut down a system
Shutting down Unix

First, see if /etc/nologin exists. (Use “ ls -lF /etc/nologin ”.) If the file does exist, back up that file if desired, as the shutdown command may (create and) modify this file.)

Shutting down OpenBSD

The halt and reboot commands should be available. In addition, the shutdown command is usually available, although it is not available during the operating system's installation (before the first system reboot). It appears that the shutdown may simply call either the halt or reboot command. (The command line parameters to the shutdown command may impact which command of the other commands, halt or reboot, gets used by the shutdown command.) Using the shutdown command has multiple nice benefits: It can add information to the /var/log/authlog, and the shutdown command can specify to shut down the system after a specified time. When the shutdown is run, the command may notify terminals being used by logged in users. Then by waiting the specified amount of time, the system ends up providing end users some time to have a chance to, in a most graceful manner, save unsaved work and perhaps delay any new tasks from being run).

The default /etc/rc.shutdown file may say:

powerdown=NO # set to YES for powerdown

In all likelihood, this is probably simply setting an environment variable which could also be set at a different time. Using this command with a variable set to YES is probably NOT a preferred approach: Instead, using a “ -p ” switch (on the command line for either the halt command or the shutdown command) is recommended, so that there is an easy way to simply leave the system left on. (The way to not power off would simply be to not include the switch that leads to the system being powered off).

If disk checking is not going to be desirable during the boot, then the shutdown command does support a -f parameter.

Shutting Down Linux
See shutdown (or perhaps Cluster Mass Service Shutdown).
Shutting Down Microsoft Windows

Windows XP and newer may have a shutdown command. There may also be a shutdown command available in the Win2K RK.

To reboot the local machine instead of a remote machine, simply leave off the “ /m \\MachineName” from the following examples.

Remotely rebooting may need to have the right software enabled, so the following instructions are not guaranteed to succeed, but they might work:

ShutDown /m \\MachineName -r

Alternatively (especially if the request seemed to be successfully received, but the restart doesn't complete), try forcing programs closed to see if that helps the restart.

ShutDown /m \\MachineName -r /f

If someone might be using the computer, and if a brief warning would be helpful (by allowing the user to notice the warning and save any unsaved changes), the following may give a 45 second warning (before forcing programs closed: -t implies /f.)

ShutDown /m \\MachineName -r -t 45

Or, to do this while leaving more of a trail in the logs:

ShutDown /m \\MachineName /r /c "optionalComment Enabling RDP" -d u:2:4 /f

There may be quite a few more ways to have Microsoft Windows restart. Some of these methods may use built-in software, like RUNDLL32, to initiate the action of restarting the system, or similar actions like logging off a user. The specific details may vary between different versions of Microsoft Windows. Rob van der woude's page about shutting down and rebooting has several details. (Note: despite the name similarly, Rob Van der woude is not clearly known to be related to Scott Conrad VanderWoude, the creator of the Cyber Pillar website.)

The SysInternals website for PsKill notes “Windows NT/2000 does not come with a command-line 'kill' utility. You can get one in the Windows NT or Win2K Resource Kit, but the kit's utility can only terminate processes on the local computer.” Perhaps the most popular download program to support shutting down a Microsoft Windows machine would be PsShutdown, downloadable as part of the latest version of PsTools (by SysInternals) and described by home page for SysInternals PsShutdown. (It is probably more likely that older versions may be more commonly deployed). This software allows a remote Windows system to be shut down using the “Remote Desktop Protocol” (“RDP”) (even if “Remote Desktop Connection” is not being used). However, newer versions of command built into the operating system (apparently available at least as early as Windows Server 2003, based on instructions from a guide @ Petri about RDP) may also be able to shut down remote systems by using “shutdown /m \\computerName”. There may be some additional options for remote computers, using VBScript provided by Rob van der woude's Windows Script Host examples page (Reboot.vbs and/or Shutdown.vbs). (Note: Despite the similarity in names, Rob Van der woude is of no clearly known relation to Scott Conrad VanderWoude, the creator of ][Cyber Pillar][.)

JP Software may have an internal reboot command.'s page on some tools for Win9x offers some Unofficial Windows 95/98/ME 32-bit improved Shutdown/Reboot/Logoff (and other) replacement tools.

As an example of some documentation straight from Microsoft, Microsoft KB Q234216: How to Exit Windows 98/Me Automatically Using a Batch File documents using “rundll32.exe shell32.dll,SHExitWindowsEx #” may provide more options, where # represents a number to Logoff (0), Shutdown (1), Reboot (2), Force (4), and/or Poweroff (8): to have multiple of those effects, add the numbers. The same KB234216 also documents “runonce -q” as exiting Windows after a 15 second delay. Note, however, that this is NOT documented to work on other versions of Windows. This inconsistency is a great reason to check out Rob's resource, noted above.

Shutting down other operating systems

OS/2 has a command called BOOT which supports OS/2's Dual Booting method, and may be used to cause a reboot.

DOS may not have a simple official way to automatically force a restart using built-in software. The three finger salute is generally sufficient for interactive use.

For automated use, check out Rob Van der woude's information about (Ab)using DEBUG: section about RESET.COM. The RESET.COM file does not come with DOS, but it can be easily created using the DEBUG command that does come with DOS (using information from Rob's page). (Note: despite the name similarly, Rob Van der woude is not clearly known to be related to Scott Conrad VanderWoude, the creator of the Cyber Pillar website.)

For even simpler automated use, although perhaps a bit less reliable (as this may not work in quite as many environments), send a single line of text to the bundled DEBUG command. Details are on Rob van der woude's page about shutting down and rebooting.

For automated use, one solution may be to download software. JP Software's 4DOS is now freeware and comes with a command: Run reboot/? from a JP Software Prompt for more details. (Online documentation of JP Software's reboot command is also available, though the online documentation may be for a newer version of the software.)

A method involving using built-in software may be to use the debug command.

[#syoffevt]: What happens when a shutdown request is made

Things will happen: generally programs will be closed cleanly/nicely, and then remaining programs may be closed forcibly, an log entry is generally made, filesystem mounts will get unmounted, and hopefully the disks will be synchronized. Then the operating system will send a signal that may cause a motherboard to reboot or may cause a power supply to power off the system (drastically reducing the amount of power provided, but perhaps providing a bit so that features like WOL may still work).

In addition to all that, there may be a way to get some custom code to run when a user account is logged off and/or when an operating system is shut down.


The operating system may support a file such as /etc/rc.shutdown for powering down the system, and for rebooting. (Similarly, the operating system may support a file for suspending/hibernating.) The file may not pre-exist, but the operating system may still support it if it does exist.

First, see what files exist with the expected filename (e.g. “ ls -Flad /etc/rc* /etc/pm/sleep.d/ ”.)

If a file with a name like /etc/rc.suspend exists, that may be a pretty good indication that it may be supported. The file might be called by the /etc/rc shell script if the shutdown parameter is provided. Warning: the prior information about rc* might have just been speculation, and the filename might not be commonly existing/supported? Another thing to check (especially if such a file does not exist) may be manual pages: If the file doesn't exist, try running “ apropos rc. ” and see what filenames are mentioned.

Julaino's response to SuperUser question about waking up from suspend refers to /etc/pm/sleep.d/ and notes a script can be added. “The script receives a single command-line parameter”. Values that might commonly be passed may include “suspend” or “resume” or “hibernate” or “thaw”. UbuntuForums post suggests naming script files to affect their order.

Backup and then edit a text file.

Determining the time when a shutdown occurred

(This is informational. This guide is covering this simply to show how this sort of information may be obtained, and isn't trying to imply or suggest anything about how much perceived reason there may be to need to try to obtain this sort of information.)

One option (which is generally not necessary, as there are generally other options that exist) may be to simply create a log as part of the process of running custom commands during a system shutdown. (For details on that, see the section about what happens when a shutdown request is made.)

Example output of a shutdown command's output from OpenBSD

shutdown -hp now TextAfterTheTimeParameterForShutdown

Shutdown NOW!
shutdown: [pid 12345]

*** FINAL System shutdown message from myusrnam@mydomain.example ***

System going down IMMEDIATELY



System shutdown time has arrived

After the restart, this information logged by the shutdown command may be noticed by running: “ sudo grep -i shutdown: /var/log/authlog ”.

If the command was run by using the sudo command, then information may be seen in /var/log/secure* files. The most recent file may be /var/log/secure which may be an easily updated text file, while older files may be text files that have been compressed by gzip for archival. They may be viewed with “ gzip -dc filename ”, or, if easier to remember, “ gzcat filename ” may be available on some systems.

The logs will show a timestamp, system name, source of the log (specifically, this is the sudo command), username, connection details, the present working directory, the user that sudo became, and the command which was run. That's quite a bit to be able to search from.

On at least some systems, something like the following may work to search for a command run by a user called “_endnow”:

{ sudo cat /var/log/secure ; sudo gzip -dc /var/log/secure.*.gz ; } | grep -i _endnow

If the shell being used doesn't support that tricky of a command line, seperate the above command lines so that cat has its output piped to grep and then, seperately, pipe the output of “ gzip -dc ” into grep.

Naturally, the above example should be adjusted based on what is being searched for. (If the system does not have a user account named _endnow, which most computers probably do not, then the above example will need customization to be of any real use.)

Determining when Microsoft Windows shut down (or started)

The most tell-tale signs that the system started up after a shutdown are some of the event log entries in the System Log. Specifically, the Windows Event Log entries related to Rebooting include events such as the event 6009 event (which also has information about what operating system version is being used) and the 6005 event which shows that the event log was started. An event 6006 event indicates a clean system shutdown. An event 6008 indicates that the system started without a proper and clean shutdown. The event ID 6008 may have a timestamp which doesn't accurately portray when the system actually restarted. The 6008 event simply estimates the time of the shutdown: the indicated time may or may not accurately indicate when the system was shut down (or noticeably stopped responding fairly well).

One way to tell when a system rebooted is to see the time from the most recent log entry that is related to the system starting up. Another method may be to check the Event Source EventLog, Event ID 6013 entries which may have a statement such as “The system uptime is 1188320 seconds.” (With some math, one can figure out that's a small number of hours short of being 1,209,600 seconds which would be nearly 2 weeks.)

[#usrtorbt]: Using a special, dedictated user account

One approach to providing a method to reboot a system may be to make a special user with permissions to reboot the machine (and perhaps no other permissions). Perhaps it may even be desirable to automatically initiate a reboot of the machine as an event that occurs when that user logs into the machine. (Logging into the user for any other purpose would likely be fruitless, as the expected result would just be that the system reboots.) Then causing a remotely-initiated reboot may be as simple as logging in as the user.

A password protected web page may allow for an easy remote ability to reboot systems without risking using credentials that may be used for other tasks. (If the credentials used to reboot a system end up getting compromised, such as if a web client successfully initiates a reboot but if that client has a keyboard logger, then unwanted reboots may occur. Those undesired reboots could cause problems, but hopefully that sort of scenario will cause comparatively limited damage compared to what could occur if the compromised credentials also had permissions to be performing other tasks that require elevated permissions. Also, hopefully the cause of the reboots will be troubleshot quickly and the compromised credentials may then be replaced.)

Make a user

Make a user called _shutdown (or _poweroff or _endnow or _stopsys or _dienow or _justdie or _reboot or some such name: the underscore isn't strictly required but is a convention to help separate automated accounts from accounts that a user may regularly log into and interact with). The section on adding a user account may provide some helpful instructions.

e.g. make a user called _endsys. Make the user able to log in via SSH. (If that means that the user needs to join a group, then do so. See: make a user become a member of a group.) There is NO need for the user to be a part of the group called “wheel”.

Prepare key files

To save some time, there are some guidelines about key handling to remember while reading the generalized directions about using a remote command. (Not all of these guidelines are likely to be applying to a single computer system.) Review these guidelines first:

Using a stand-alone image, or a child image (that isn't expected to also be used as a base image)
If no suitable keys are readily available

If no such key is available, then generate SSH key files (and keep the key files around for use by other systems). The key that is manually created will be used by the SSH client. (The server will also need a key, but that may already have been taken care of automatically, so that may not be a need for concern.)

Then begin the process of installing the public key file into the user's directory on the server: do start by backing up any files that will need to be changed. Go ahead and skip the section about Using an (OpenSSH) SSH key to use (only certain) commands: even though that is the main goal here, it will make sense to set that up after fully testing the new key that was just created. Head on down to the instructions about the required contents of the ~/.ssh/authorized_keys*, and follow the next couple of sections which are the section about placing the needed contents into the authorized_keys* file and setting up permissions. Then, follow the steps for testing an OpenSSH key.

Using existing keys

If there is a likelihood that a suitable (uncompromised) public key has been previously generated, locate that public key. (The private key will be needed later, for testing and for making the public key really be useful.) Using the existing keys should often save time, compared to generating a new key, and key management may somehow be simplified if key re-use results in a reduction in the total number of keys that are actively set up.

When setting up a base image

For a base image, which may be used to create child/snapshot images for virtual machines or cloned hard drives from, remember not to actually bother with putting any long term public key into the authorized_keys file, because that one specific act will waste time both now and later. (It will waste time now by putting in a key that cannot be used, and it will waste time later whenever support for such a key needs to be removed every time a new child image is created.)

However, one can benefit by creating the user account, making sure that the user account has permissions to log in remotely, setting up the sudoers file, and creating the ~/.ssh/authorized_keys file with the needed permissions (even if the file is left completely blank).

One option may be to generate SSH key files that will be used for the short term. Expect these files to be temporary. Then verify that everything is functioning as desired. But then remove the public key. Also, in case some expert attacker ends up performing an unlikely attack of data recovery of a deleted key, ensure that the temporary private key file absolutely never gets into the wrong hands. A way to help do that is to delete any and all copies of the private key file. (For more secure environments, make sure the private key file isn't recovered, by wiping.) Once all copies of the private key file are removed, any related files (like the public key) should also be removed because they are useless (or, at least, errr... well, they should be useless, if cryptography theories are sufficiently sound).

Follow the steps, as needed, for deploying public keys that work with an SSH client's private key, including adding support for restricting the key to only work with certain commands. When restricting a key to work with only certian commands, it is recommended to start with a simple command, like perhaps copying a file in the user's home directory, for testing purposes. Keep it simple before adding the complexity of dealing with elevated privileges.

Using a dedicated user with Unix
[#prmsyoff]: Handle /etc/sudoers file

As a standard practice, back up the /etc/sudoers file before making changes.

Set sudo to only allow user to run certain authorized commands (or commands that start in certain ways). Details are in the section about running commands as superuser: section about restricting commands.

If the user's name is _endsys then the /etc/sudoers file may have something like:

_endsys  ALL=(ALL) NOPASSWD:/sbin/shutdown -h*, SETENV: ALL

Alternatively, the configuration file may authorize a group instead of a username. To do this, place a percent sign at the start of that line, and reference the group name instead of the username (if the group name is different than the username). By having a group have access to shut down the system, another user can be added to the group instead of requiring a change to this configuration file. (That may be more consistent with a very common practice, which is the practice of using groups to effectively manage permissions.)

Allow restricted remote login

This is mostly about applying some information in the section about deploying an SSH key file so that a server will accept it, including applying information in the sections about including restrictitions, restricting to only use a certain command, and combining that with sudo restrictions on what may be run as a superuser. This section provides some specifics about using that method to cause a computer to shut down.

Allow the user to log in remotely and to run certain commands such as the sudo command provided.

The .ssh/authorized_keys (e.g. ~_endsys/.ssh/authorized_keys if the user is named _endsys) may have a command line such as the following to attempt to power off the system in OpenBSD.

The following command line examples use an environmental variable called $USER. That is a BSDism: Other systems may not use $USER but may have a variable called $LOGNAME (which some online documentation about crontab notes as being“set automatically by the cron” software). In some systems, including OpenBSD, both $USER and $LOGNAME may exist and Wikibooks's Guide to Unix Environmental Variables notes that these variables “should have the same setting and purpose”. Even for operating systems that typically only automatically support just $USER XOR $LOGNAME, and not both values, the man page for OpenSSH client ssh shows that OpenSSH may set both environment variables.

command="sudo /sbin/shutdown -hp now Shutdown initiated with SSH by \\"$USER\\" CONN rem/lcl=\\"$SSH_CONNECTION\\" CLI rem/lcl=\\"$SSH_CLIENT\\" CMD=\\"$SSH_ORIGINAL_COMMAND\\"",no-agent-forwarding,no-port-forwarding,no-X11-forwarding 

To create a line like that from a command line, replace the ~ in the following example with ~username (if not logged in as the user who is having the file modified).

echo -n command=\"sudo /sbin/shutdown -hp now Shutdown initiated with SSH by \\\\\\\\\"\$USER\\\\\\\\\" CONN rem/lcl=\\\\\\\\\"\$SSH_CONNECTION\\\\\\\\\" CLI rem/lcl=\\\\\\\\\"\$SSH_CLIENT\\\\\\\\\" CMD=\\\\\\\\\"\$SSH_ORIGINAL_COMMAND\\\\\\\\\"\",no-agent-forwarding,no-port-forwarding,no-X11-forwarding" "| sudo -n tee -a ~/.ssh/authorized_keys

Note, the above is simply a portion of the line needed. (In some cases, the rest of the line may consist of a space followed by the contents of the public key file.) For further details, see: sections about including restricting to only use a certain command and combining that with sudo restrictions on what may be run as a superuser.

Note: If making a base image, it may be desired to not include the key. The expectation would simply be that a key gets inserted as a standard process that gets performed when a new image gets created from this base image. In this case, it may be nice to not have the line end with newline character(s) (like a line feed). This way, a public key may be concatinated to the end of the file, creating a complete line. (Users of nano may benefit from using the -Lw options.) Note that the above example does show a space character after the options. This is very intentional (and required).

Once the key is taken care of, the SSH client may then initiate a reboot. For example:

ssh -i aPrivateKeyFile -l userThatWillShutDown -p 22 remoteHostNameOrIP /bin/echo Parameters for command on remote system

Note that with the above command, the SSH client will attempt to run an echo command. The client will not succeed in running whatever command it tries to if the server needs to run a specific different command whenever it accepts the specific key that the client provided. However, there is a point to this: the command entered by the client will show up in the $SSH_ORIGINAL_COMMAND environment variable on the server. The server can use this as it sees fit, such as running the requested command or logging what the command was. By using this method, the server can log information (such as what IP address the client came from) and, if the server is configured to cause this to happen, the client has an effective way to log additional information (such as a custom message, like a reason for the shutdown).

[#rbtfrweb]: Using the web

To perform this, make a command that will restart a system. Restarting a system may require elevated privileges: a way to handle that is described in the section about making a user dedicated to reboot. If that process is followed, then anybody who can SSH can reboot the system as long as they have the needed credentials. So rebooting can then be as simple as running a command.

As for allowing a web user to be able to run the command, that is simply a matter of using appropriate security to prevent unauthorized requests, and then having authorized requests run the command using CGI. (All of this is doable in Unix. However, these instructions may not be very complete. Then this solution can used by any method that is able to access that page (including authenticating successfully). That may include automatic methods, although such methods should be careful to not cause credentials to be made available. For example, specifying the credentials on a command line is something that will expose those credentials to anybody who may be looking at the command line, and so that can certainly be a vulnerability when that situation isn't being handled appropriately.

[#acpistop]: ACPI

This section be in a fairly unfinished state right now. It is being provided anyway, in case it is of any use to anybody.

For more information about ACPI, see section about ACPI.

Does qemu send such a signal with system_powerdown from the monitor, or does it simply turn off the machine similar to what losing power would do?

For VMWare / Windows, see some ACPI-related info at VMWare page about ACPI and Windows. forum post about ACPI and Qemu has/had the statement, “It is my experience that acpi emulation in qemu is not stable enough for windows guests. It would be interesting to know if you can achieve a stable configuration.”

URL suggests libvert may be useful. ACPI coding

[#upssysdn]: Responding to a signal from a UPS

First, start by seeing the short basic information about using UPS battery backup units. This may not be critical information, and not everybody who has UPS's may know all of it, but it may still be good to know.

“Network UPS Tools” (“NUT”)

See the NUT hardware compatibility list (for the stable version).


“Random Bits” blog post on “Monitoring a UPS with nut on Debian or Ubuntu Linux” says “There are two different ways to monitor a UPS with nut: either expose the UPS hardware to GNOME Power Manager through hal or monitor the UPS directly with upsmon and upsd.” It concludes “Don?t use nut-hal-drivers unless you really, really want a fancy notification icon.” (There are disadvantages to that method.)

This guide to supporting NUT in Unix largely comes from Calomel's guide for using NUT UPS software shows how to set up the configuration files and interact with a USB APC. That guide might be rather specific to OpenBSD, and so there may be some adaptation required for things to be working on other operating systems. This may not have been tested yet. This may not have been tested for non-physical hardware (virtual machines) yet.

Identify how the device will be communicating to the computer. If this is a USB device, use tools to detect the device. (If USB is not being used, these directions may need further modification.)

Make sure that there is not an existing group called _ups that can't be used for this purpose. (The section about Groups has some rather related information that may be helpful for this task.)

Install the Network UPS Tools (which is a package called “nut”). (A package manager doing this may add dependencies such as libusb and neon.)

This should create a group called _ups. Modify ownership (possibly using some information that is in/near the section on file attributes/ownerships/permissions) of the relevant /dev/*usb* file so that it is owned by the group _ups or another group of which _ups is a member.

Modify /etc/nut/ups.conf. An example completed file is provided, followed by a description of how each line was decided upon.

user = _ups [myusbups] driver = usbhid-ups port = auto pollfreq=60 desc = "My Description Of My UPS Device"

Specify the user to run as. e.g. a line saying “user = _ups” Then specify a “group” of commands related to a single UPS. e.g. on the next line place “[myusbups]” Specify the driver and the port. The driver “usbhid-ups” may be a good choice for “fully supported” devices (using the terminology from Calomel's guide for using NUT UPS software). (Use “driver = usbhid-ups” For the port, one may be able to use “port = auto” (as noted by “Random Bits” blog post on “Monitoring a UPS with nut on Debian or Ubuntu Linux”) or may specify a device such as “port = /dev/ugen0.00” (as shown by Calomel's guide for using NUT UPS software). While editing the same file, one may assign a polling frequency (e.g. “pollfreq=60”) and a description (e.g. “desc = "My Description Of My UPS Device"”) according to the example at Calomel's guide for using NUT UPS software.)

Start the UPS driver. /usr/local/bin/upsdrvctl start

At this point, the output from /usr/local/bin/upsdrvctl may show which subdriver is being used. That may be a good sign to show that the driver is indeed identifying the UPS well.

Modify some more configuration files. /etc/nut/upsd.conf has an excellent description and example from Calomel's guide for using NUT UPS software. The example file is:

##  upsd.conf
ACL all
ACL localhost
ACCEPT localhost

Modify /etc/nut/upsd.users according to the directions at Calomel's guide for using NUT UPS software. (It seems that this is referring to actual users already created on the system.)

Start the NUT UPS daemon called upsd which may be in /usr/local/sbin/.

Use the upsc program to ensure client access works. (Although Calomel's guide for using NUT UPS software uses an example command of “ upsc apc@localhost ”, it seems likely that the portion between the space and the at sign should be a user in the /etc/nut/apc.users file. So, try using an appropriate local user if that approach seems more appropriate.)

Monitor this: This involves /etc/nut/upsmon.conf. Calomel's guide for using NUT UPS software has a fairly elaborate one which seems to reference the file “/etc/nut/”. It also references apc@localhost which is probably referring to a section called “apc” within the /etc/nut/ups.conf example that the site uses earlier. The /etc/nut/upsmon.conf from Calomel's guide for using NUT UPS software also seems to reference a non-existant file /etc/nut/killpower.

If using the /etc/nut/upsmon.conf from Calomel's guide for using NUT UPS software, then create the referenced file “/etc/nut/

Then start upsmon which may be located in /usr/local/sbin/ and which may appear with two PIDs (one of which is running with privilege restrictions).

Finally, once it seems like the software is behaving properly, add to the system startup files. For OpenBSD, “ pkg_info -M nut ” (after the package “nut” is installed) shows this message:

Install Message for OpenBSD's “nut” package
Once you have the config files under /etc/nut set up properly, the
following block can be added to your /etc/rc.local file to start nut.

# Start Nut
if [ -x /usr/local/bin/upsdrvctl ]; then
echo -n ' nut'
/usr/local/bin/upsdrvctl start > /dev/null 2>&1
/usr/local/bin//usr/local/bin/upsd start > /dev/null 2>&1
/usr/local/bin//usr/local/bin/upsmon start > /dev/null 2>&1

Note that the above text is OpenBSD-specific: Namely /etc/rc.local is a startup file with OpenBSD but is not commonly supported by other distributions. For other distributions, become familiar with the operating system startup file(s) and put the commands into there.

Other NUT-related software may include: nut-cgi (OpenBSD/i386 4.6 package information for nut-cgi refers to which is the main website for NUT), p5-UPS-Nut (referenced by the OpenBSD/i386 4.6 package information forp5-UPS-Nut), libups, KnutClient (see also: KNutClient. Web page was previously at the location archived by archive of page for KNutClient).

Microsoft Windows

To interact with a server using NUT, may be of some use. The Unix tools may also be able to be used with Windows (using Cygwin).

An open source option

The APC UPS “daemon” software, APCUPSD:
Brief description from OpenBSD/i386 4.6 packages

Closed source options

The following software is not known to have publicly released source code.

There are various pieces of software such as the “Network Shutdown Tool” and software which uses the PowerChute brand name, such as “APC PowerChute Business Edition” (“PBE”).

Some custom solutions?
Note that chances seem high that at least some UPS monitoring software simply looks for a specific signal. That signal might be fairly easy to replicate, even from software that doesn't interact with the UPS. (This might be a way to remotely shut down a system, even if the signal originates from a custom program rather than from a UPS.) This might be a good (providing options), or bad (be sure to secure the UPS monitoring program so that false signals may not be sent to it).
Other methods
Of course, having an available local user (who may be able to unplug a power cord) may also be an option to get a system powered off. Another method, which for most operating systems will likely result in a less clean shutdown, is to tell the UPS to power off that power port (or the entire UPS, although quite likely it may not be possible to turn the UPS back on remotely if doing that). If the goal is simply to reboot a Windows system, one option (which may or may not work well, possibly depending on the system) may be to terminate a critial program such as the Client/Server Runtime Subsystem (csrss.exe).