Use this HTA to communicate with users when they log on
On Linux or Unix systems, you can use the motd command to display a "message of the day" file that appears when users log on to their systems. In Windows, displaying a message from a logon script is typically the only way to guarantee users are going to see the message. (Whether users will actually read the message is a different matter.)
There are many ways to display a message to users from a logon script. If you're using a shell script or a console-based Windows Script Host (WSH) script, you can output text to the console window, although doing so isn't the best way to attract attention to a message. If you're running a WSH script with the WScript host, the WScript.Echo method displays the message in a message box with the title "Windows Script Host" and an OK button. However, the title, icon, and buttons aren't customizable. You can also use the WshShell object's Popup method, which lets you customize the title, icon, and buttons and includes a timeout feature that automatically dismisses the dialog box after a specified amount of time. Although the Popup method is useful, you can't specify a font, change the color scheme, or add a scroll bar for longer messages.
Rather than just dealing with these limitations, I decided to write an HTML Application (HTA), MOTD.hta, to display a message of the day. An HTA leverages HTML's customization features to provide a superior GUI.
Listing 1 contains an excerpt from MOTD.hta. You can download the complete HTA, which is fully commented, by clicking the Download the Code Here button at the top of the page. You can use MODT.hta by itself and in a logon script. After I show you how to do so, I'll explain how the HTA works, including how it constructs the HTML markup.
Using the HTA is simple. First, create a text file named MOTD.txt that contains the target message. Then, place that text file in the same directory as MOTD.hta and execute the HTA. Because an HTA is an HTML document, your ability to customize its appearance is limited only by your knowledge of HTML and Cascading Style Sheets (CSS). Figure 1 shows an example of the HTA's appearance.
You can move MOTD.hta to a different share by editing the MESSAGE_FILE_NAME variable, which callout B in Listing 1 shows. You need to specify a Universal Naming Convention (UNC) path to the message file in the following format:
Make sure you double each backslash (\) in the path because it is JScript's escape character (i.e., \\ means \). For example, if you were to move the MOTD.txt file to the share \\Server1\MOTD, you'd use the following code:
var MESSAGE_FILE_NAME = "\\\\Server1\\MOTD\\MOTD.txt";
Using MOTD.hta as a Logon Script
It's simple to run MOTD.hta at logon by adding it to a Group Policy Object (GPO) as a logon script. I assume you're already using one or more GPOs to manage your domain, so I won't describe how to create a GPO. To add MOTD.hta to an existing GPO, follow these steps:
- Open the Microsoft Management Console (MMC) Active Directory Users and Computers snap-in (dsa.msc).
- Right-click the organizational unit (OU) that contains the user accounts, and choose Properties.
- Click the Group Policy tab.
- Double-click the GPO you want to modify.
- In the GPO's console tree, go to User Configuration/Windows Settings/Scripts (Logon/Logoff).
- In the right-hand pane of the GPO console, double-click Logon to display the Logon Properties dialog box, which Figure 2 shows.
- Click Show Files at the bottom of the Logon Properties dialog box to display the GPO's logon scripts folder in a Windows Explorer window. Copy the MOTD.hta file into this folder. If you haven't modified MOTD.hta to move the message file's location, you'll need to copy the MOTD.txt file into this folder as well. Close the Windows Explorer window.
- Click Add in the Logon Properties dialog box to display the Add a Script dialog box. Enter MOTD.hta as the script's name, as Figure 3 shows. Click OK to close the Add a Script dialog box, then click OK to close the Logon Properties dialog box.
An HTA is a Dynamic HTML (DHTML) document that executes at a higher level of trust than Microsoft Internet Explorer (IE) uses when displaying standard HTML documents. Because HTAs execute at a high level of trust, they execute as local applications, which have access to all available ActiveX objects, including those not marked as safe for scripting in IE.
The "dynamic" part of DHTML means that the HTML document executes script code in response to events. For example, MOTD.hta executes its script code in response to two events: the onload and onkeypress events of the body object. In other words, the executeApp function executes when the document is done loading, and the keyboardHandler function executes when a key is pressed.
Let's take a closer look at the executeApp function. First, the executeApp function declares a set of variables for its own use, then it calls the moveTo method of the window object to center the HTA's window on the screen. Callout C shows how the executeApp function subtracts the document's width and height from the screen's width and height and divides the results by two, thus centering the window on the screen.
Next, the executeApp function creates an instance of the FileSystemObject object and checks to see whether the MESSAGE_FILE_NAME variable contains any backslashes. If MESSAGE_FILE_NAME doesn't contain a backslash (i.e., the variable doesn't contain a path), the executeApp function needs to determine the location of the MOTD.hta file. So, the function uses the location object's pathname property to retrieve MOTD.hta's full path and filename, then it uses the FileSystemObject object's GetParentFolderName method to extract MOTD.hta's path. If MOTD.hta's path contains spaces, the pathname property returns the string %20 in place of each space character, so the executeApp function uses the unescape function to convert these strings to spaces. Finally, the executeApp function uses the FileSystemObject object's BuildPath method to return a complete pathname to the message file. Note that if the MESSAGE_FILE_NAME variable contains a backslash, the function simply uses the MESSAGE_FILE_NAME variable's value as it is.
At this point, the executeApp function has the full path and filename to the message file. The function then attempts to open the message file as a TextStream object by calling the FileSystemObject object's OpenTextFile method. In case of a runtime error, the function encloses the OpenTextFile method call inside a try…catch…finally statement. If the function successfully opens the message file, it uses a while statement to read each line from the message file and constructs a string containing HTML markup. (I'll discuss how the executeApp function creates the HTML markup in a moment.) If an error occurs when the function attempts to open the message file, the code in the catch block executes instead, setting the HTML message string to an error message.
Next, the executeApp function updates the document with the HTML message string. Callout E shows how the executeApp function changes the <div> element's innerHTML property by using the document object's getElementById method.
If you want the message of the day to disappear after a certain amount of time, uncomment the line of code in callout F and change the number of milliseconds in the setTimeout method's last parameter. The value 30000 means that MOTD.hta will close after 30 seconds. For example, if you want MOTD.hta to close after one minute, you would use the following code:
window.setTimeout ("window.close();", 60000);
Constructing the HTML Markup
One of the advantages of using an HTA to display the message of the day is that you can use HTML to display the message. MOTD.hta is set up to read plain text and convert it into HTML markup. As callout D shows, the executeApp function reads a line of text from the message file. If the line of text is at least one character long, the executeApp function encloses the line of text within <p> and </p> tags. If the line is blank, the executeApp function creates a blank line by enclosing the (nonbreaking space) HTML entity within <p> and </p> tags. Lastly, the executeApp function appends the <p> and </p> tags and the contents between them to the message text. Thus, you don't need to enclose paragraphs between <p> and </p> tags in the message file for MOTD.hta to display the message properly. If the message file contains a blank line, it will appear as a blank line in the MOTD.hta window when it executes.
You can use HTML markup to draw attention to certain parts of the message. For example, you can bold text by enclosing it within <b> and </b> tags.
If you put hard returns at the end of each line in the message file, MOTD.hta will read these as separate paragraphs for the HTML markup, meaning that the formatting might look odd depending on your users' screen resolution and font sizes. To avoid this problem, I recommend placing hard returns only at the end of each paragraph. If you edit the message file with Notepad, you can enable the Word Wrap setting on the Format menu. That way, you can see all the text in a paragraph without having to scroll sideways, thereby resisting the temptation to add hard returns in order to see all the text.
Because MOTD.hta is an HTML document, you have a lot of flexibility in determining its appearance. The <style> element shown in callout A contains the CSS rules that determine how the document is displayed. For example, if you want to use 12-point sans serif for the message text's font, you would use the following CSS rule:
font: 12pt sans-serif;
For more information about CSS, go to http://htmlhelp.com/reference/css/.
Getting the Word Out
Sometimes it's difficult to get information out to your users in a timely manner. MOTD.hta addresses this problem by providing an easy way to attractively display important information to your users.