Creating a Message of the Day banner using a HTA

by Jeremy Saunders on December 28, 2007

A customer asked me to assist with implementing a “Message of the Day” (MOTD) banner into their logon scripts. I had written one years ago that was part of a kix32 script, but found that it no longer worked with the wkix32 script processor. I guess that I could have debugged it and fixed it up, but it was old and tired, and needed a face lift. I was always keen to write one using a HTA (HTML Application), so took this opportunity to do so. In my opinion a HTML Application provides a far more professional look for the users.

When I sat down and designed the application I wanted to implement the following features:

  • Separate the MOTD text into a text file, motd.txt, so that no one was actually modifying the HTA itself. This is also how my old kixtart one worked.
  • Have it look for the motd.txt file in the same location as the HTA itself.
  • Provide the ability to supply a command line argument to look for the motd.txt file on a common file share, such as the “netlogon” share on Domain Controllers, which would be “%LogonServer%\netlogon”.
  • If the motd.txt file is missing, close the application. This is important, as it allows you to leave the HTA in place with the existence of the text file determining whether or not it runs.
  • It was also important that the text from the motd.txt file is read in as it is typed. ie. No need to consider formatting, etc. To address this, my script simply appends a <BR> html tag to the end of each line. The <BR> tag provides a carriage return and line feed.
  • I didn’t want multiple instances to run in the same user session at the same time. This can easily be controlled by using singleInstance property of the HTA Application.
  • I didn’t want users being able to simply close or minimise the application. This can easily be controlled by using sysMenu property of the HTA Application. In fact, the only way for them to close the application is for them to accept that they have read and understood it. Unfortunately, if they have permission to do so, they can end the mshta.exe task from Task Manager. This may well be the case for some Desktop/Notebook fleets, but not on locked down Citrix/Terminal Servers.

I looked around on the Internet, but really only came across one sample from Bill Stewart. His article was titled Got Something to Say? Display a Message of the Day. The article and concept was good, and exactly what I was looking for, but the code itself, in my opinion, was not. Although in fairness, Bill had written his application in JavaScript, whereas I was looking for one in VBScript. I personally find VBScript to be cleaner than JavaScript.

It took me a while to get my head around the VBScript code for a few of the features I wanted to implement, as a HTML Application only supports pure VBScript and not the added commands I am used to using with the WScript/CScript Windows scripting host.

If you open a HTA using IE, you will get a security prompt. So to open the HTA silently without the IE security prompt you have two options:

  1. Associate .hta extensions with mshta.exe (Microsoft HTML Application host), the script host for a HTA, which is found in the %SystemRoot%\System32 folder. Then just double click or open the HTA itself.
  2. Simply launch it from the command line using mshta.exe in the syntax.
    i.e. mshta.exe motd.hta

Passing command line parameters/arguments was a challenge until I came across a great Microsoft article by the “Scripting Guy” called How Can I Pass Command-Line Variables to an HTA When It Starts?. It provided me with the exact code required.

So if using command line parameters, you need to use quotes around them. For example:

mshta.exe motd.hta “netlogon”

If you read the Scripting Guy’s article, you will understand that the first argument is array member 3, second is 5, etc. But we are only concerned here with array member 3.

Now I have the mechanism to launch the HTA via the two methods I was looking for in my design.

  1. mshta.exe motd.hta – This will look for the motd.txt file in the same location as the motd.hta.
  2. mshta.exe motd.hta “netlogon”– This will look for the motd.txt file in the %LogonServer%\netlogon share.

Update from 27th March 2012

I received a lot of feedback to suggest that the HTA flashes on the screen and closes. This is due to the parameters not being passed correctly, and therefore the HTA is closing because it cannot find a valid motd.txt file. So I updated the Window-Onload subroutine as per the following:


Sub Window_Onload
 Dim strMOTDFile, arrCommands, strFullName, arrFullName, strScriptFileName, strLogonServer
 Dim strCommonPath, strPath, strcurrentPath, strLine, strContents, i, WshShell, oFSO, objFile

Set WshShell = CreateObject("WScript.Shell")

strMOTDFile = "motd.txt"
 arrCommands = Split(objHTAInfo.commandLine, chr(34))

strFullName = replace(objHTAInfo.commandLine,chr(34),"")
 arrFullName = split(strFullName,"\")
 strScriptFileName = arrFullName(ubound(arrFullName))

' Uncomment the next three lines for testing only.
' For i = 3 to (Ubound(arrCommands) - 1) Step 2
' Msgbox arrCommands(i)
' Next

If Ubound(arrCommands) < 2 Then
 If instr(1,arrCommands(0),"Netlogon",1) = 0 Then
 strcurrentPath = replace(strFullName,strScriptFileName,"")
 strPath = strcurrentPath
 Else
 strLogonServer = WshShell.ExpandEnvironmentStrings("%LogonServer%")
 strPath = strLogonServer & "\Netlogon\"
 End If
 ElseIf Ubound(arrCommands) = 2 Then
 If (arrCommands(2) = "" OR arrCommands(2) = " ") AND instr(1,arrCommands(1),"Netlogon",1) = 0 AND instr(1,arrCommands(2),"Netlogon",1) = 0 Then
 strcurrentPath = replace(strFullName,strScriptFileName,"")
 strPath = strcurrentPath
 ElseIf instr(1,arrCommands(1),"Netlogon",1) > 0 OR instr(1,arrCommands(2),"Netlogon",1) > 0 Then
 strLogonServer = WshShell.ExpandEnvironmentStrings("%LogonServer%")
 strPath = strLogonServer & "\Netlogon\"
 Else
 ' Note that there are two different ways for presenting the path
 ' strcurrentPath = Left(document.location.pathname,InStrRev(document.location.pathname,"\"))
 strcurrentPath = Replace(Left(document.location.pathname,InStrRev(document.location.pathname,"\")),"%20"," ")
 strPath = strcurrentPath
 End If
 ElseIf Ubound(arrCommands) = 3 Then
 strLogonServer = WshShell.ExpandEnvironmentStrings("%LogonServer%")
 strPath = strLogonServer & "\Netlogon\"
 Else
 If instr(1,arrCommands(0),"Netlogon",1) > 0 OR instr(1,arrCommands(3),"Netlogon",1) > 0 Then
 strLogonServer = WshShell.ExpandEnvironmentStrings("%LogonServer%")
 strPath = strLogonServer & "\Netlogon\"
 Else
 strcurrentPath = replace(strFullName,strScriptFileName,"")
 strPath = strcurrentPath
 End If
 End If

' Uncomment the next line for testing only.
' Msgbox "Path to " & strMOTDFile & " is:" & strPath

Set oFSO = CreateObject("Scripting.Filesystemobject")
 If oFSO.fileexists(strPath & strMOTDFile) Then
 Set objFile = oFSO.OpenTextFile(strPath & strMOTDFile, ForReading)
 Do Until objFile.AtEndOfStream
 strLine = objFile.ReadLine
 strContents = strContents & strLine & "<BR>"
 Loop
 objFile.Close
 document.getelementbyid("textarea").innerHTML = strContents
 End If

Set WshShell = Nothing
 Set oFSO = Nothing
 Set objFile = Nothing
 End Sub

Update from 20th August 2013

I received feedback that the HTA was not working correctly with IE9 and IE10. I found that the code needed to be enhanced in two places:

1. Set the <!DOCTYPE> declaration for HTML 4 at the very top of the script as per the code below:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">

2. Set the http-equiv attribute to be compatible with IE8 within the <head> entry as per the code below:

<head>
<meta http-equiv="X-UA-Compatible" content="IE=8"/>
<title>Message of the Day</title>

The following screenshot is an example of what the MOTD HTA looks like when running.

There are four ways that you can implement this:

  1. Chain or call it from an existing logon script.
  2. Add it as a Logon Script in a Group Policy Object.
  3. Add it to the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run key on all computers.
  4. Add a shortcut to the “%ALLUSERSPROFILE%\Start Menu\Programs\Startup” folder on all computers.

Download the code: motd.zip

Future enhancements:

  • Log the acceptance to a file or registry before closing the application. This can provide some legal and compliance tracking if needed.
  • Add the customers logo into the application. This is simple to do, but I need to consider where on the banner to locate the logo, and how I can construct some code that manages different size logos.
  • Implement different messages based on Group Membership. Could be of value to different organisations. You can actually do this already using multiple Group Policy Objects. However, my idea was to implement this by using different group membership tags within the one motd.txt file that would expose different lines and paragraphs to users depending on their group membership. Probably more complex than it needs to be, but would make a nice feature.

Please feel free to use as you wish and provide any useful feedback you feel may be of benefit to others.

Jeremy Saunders

Jeremy Saunders

Technical Architect | DevOps Evangelist | Software Developer | Microsoft, NVIDIA, Citrix and Desktop Virtualisation (VDI) Specialist/Expert | Rapper | Improvisor | Comedian | Property Investor | Kayaking enthusiast at J House Consulting
Jeremy Saunders is the Problem Terminator. He is a highly respected IT Professional with over 35 years’ experience in the industry. Using his exceptional design and problem solving skills with precise methodologies applied at both technical and business levels he is always focused on achieving the best business outcomes. He worked as an independent consultant until September 2017, when he took up a full time role at BHP, one of the largest and most innovative global mining companies. With a diverse skill set, high ethical standards, and attention to detail, coupled with a friendly nature and great sense of humour, Jeremy aligns to industry and vendor best practices, which puts him amongst the leaders of his field. He is intensely passionate about solving technology problems for his organisation, their customers and the tech community, to improve the user experience, reliability and operational support. Views and IP shared on this site belong to Jeremy.
Jeremy Saunders
Jeremy Saunders

Next post: