Periodically, you might have to shut down specific servers for maintenance or even shut down an entire data center for relocation. Despite efforts to inform users of the shutdown, a few users might still be unaware of the event, so an important last step just before the shutdown is to send users a message about the impending outage. The script ShutdownMessage.bat automates the delivery of such messages.
ShutdownMessage.bat sends a shutdown message to all users who are currently connected to the affected servers. You can customize the message for each server by noting the resources that will be unavailable, when the outage will start, and about how long the outage will last. After you execute the script from a central server or workstation, ShutdownMessage.bat uses the Net Send and Net Session commands, Sysinternals' freeware PsExec utility, and a neat scripting trick to deliver the customized shutdown message.
Net Send and Net Session
The Net Send command uses the Messenger service to deliver messages. You can use this command several ways. You can direct a message to one user or computer. You can direct a message to all the users or computers in the domain or all the users or computers currently logged on to the domain. Finally, you can direct a message to users who are currently accessing resources on the local server.
I initially decided to use the Net Send command to send a message to users accessing resources on the local server to be shut down. This command usage has the syntax
Net Send /users message
where message is the text you want to send. However, when I tested the command, I discovered that most of the users received duplicate messages. This situation is a classic example of a command that looks good but, when tested, fails to meet expectations.
To determine the problem, I ran the Net Session command to identify the sessions between the local computer and the clients connected to that computer. I found that nearly every user session had an IPC$ connection and a second session that specified the user's open files. The Net Send command doesn't provide a way to eliminate such duplicates, so I developed a workaround, which Listing 1 shows. I piped the Net Session command's output (i.e., a list of connected client machines) to a subroutine called Remdup. Remdup skips a machine entry in the list if the script has already sent a message to that machine.
Testing Remdup showed that the subroutine would effectively stop the script from sending duplicate messages. However, adding this routine meant that I would have to run the script locally—a time-consuming task. Enter PsExec.
PsExec and the Scripting Trick
Typically, remote operation requires the installation of server and client software. But PsExec lets you execute programs remotely without installing any client software. You just install PsExec on the server, then use the command
PsExec.exe \\servername -c ClientFileLocation
where servername is the name of the remote server and ClientFileLocation is the location to which you want to copy the program. The c switch prompts PsExec to temporarily copy the program to the remote server. The server then interactively executes that program. If you leave out the ClientFileLocation parameter, PsExec copies the program to the machine's system path by default.
In my case, using PsExec was an ideal solution. However, to use PsExec, I needed two scripts: one script that launches PsExec against a list of remote servers and another script that PsExec executes on those servers.
One scripting trick that comes in handy is using one script to create another script. This trick reduces the number of scripts you need to configure and deploy. Thus, I used ShutdownMessage.bat to create the script Client.bat, which PsExec executes on the remote servers. As Listing 1 shows, I began every line that creates Client.bat code with the Echo command and ended the line with the double greater than (>>) redirection symbol followed by %ClientBat% (i.e., the environment variable that represents Client.bat). This setup directs the output of the commands sandwiched between the Echo command and the >> redirection symbol to Client.bat. (For information about the >> redirection symbol, see the Web-exclusive article "Shell Scripting 101, Lesson 4," http:// www.winscriptingsolutions.com, InstantDoc ID 20530.)
In the sandwiched commands, I used the caret (^) to flag, or escape, reserved shell characters (i.e., characters that have a special meaning in the command shell), such as the pipe (|) and ampersand (&) symbols. Escaping these characters prevents the command processor from running them as code in the main script (in this case, in ShutdownMessage.bat).
In the sandwiched commands, I also doubled the percent (%) signs so that % becomes %% and %% becomes %%%%. I added the extra % signs because the original % signs disappear when the command processor executes the Echo command. Doubling the % signs ensures that Client.bat has the % signs it needs.
You can find ShutdownMessage.bat in the Code Library on the Windows Scripting Solutions Web site. ShutdownMessage.bat works on machines running Windows 2000 Professional, Win2K Advanced Server, Windows NT Server 4.0 Service Pack 6 (SP6), or NT Workstation SP6.
To use ShutdownMessage.bat, you need to download PsExec 1.23 or later (http://www.sysinternals.com/ntw2k/freeware/psexec.shtml) into the same directory as ShutdownMessage.bat on your machine. You then need to configure ShutdownMessage.bat for your environment. In the script, you'll find comments that point out the code you need to customize. The customizations include
- the path to PsExec
- the location in which you want to create Client.bat
- the names of the servers that the shutdown affects
- the text in the shutdown message
After you customize the script, you can schedule it to run on the day of the outage at the appropriate time. At the specified time, ShutdownMessage.bat will deliver a message to all connected users warning them about the impending shutdown.