Windows 1E NightWatchman Agent scripting reference

What NightWatchman power-off scripts do

NightWatchman is designed to ensure that systems are shut down or logged off in a consistent manner. This takes the onus off the user to shut down their machine and assists in desktop management, software delivery and energy saving.

Being able to shut down systems is only half the solution; the other half requires a means of saving open, edited files on the machine being shut down. In NightWatchman this task is performed by the power-off scripts.

Power-off scripts are run by NightWatchman before initiating a power-off. The purpose of the scripts is to protect unsaved data before power-off can commence by interacting with the open application windows.

  • A particular script is designed to shut down a particular process.

  • The script for a process will run at least once for each running process.

  • A particular script may be run multiple times if the process has multiple open documents.

  • The scripts are designed to fail with an error if anything unexpected happens.

An important point to remember is that NightWatchman scripts are designed to protect data. In the event of any problems being encountered by the scripts the power down sequence will abort to prevent loss of data.

When NightWatchman begins a power-off or log-off operation, it performs the following sequence of actions for each top-most application window in each Windows session:

  1. Find the process the window is running in.

  2. Find a NightWatchman script in the NightWatchman scripts directory with the same name as the process.

  3. Run the script with CScript.exe. The window handle (HWND) of each application window will be passed on the command line to the script.

Any given process may have multiple windows open, representing different documents. The corresponding scripts will be run in turn for each window. For example, you may be editing a number of documents in Microsoft Word. In this instance, there is one process that represents Microsoft Word and one corresponding NightWatchman power-off script. The script will be run multiple times, once for each open Microsoft Word document.

Power-off script development

There are many ways of developing NightWatchman power-off scripts. We recommend one particular way that makes the process of developing a script for a particular application easier. A NightWatchman power-off script can be written in VBScript to handle the intelligent shutdown of applications, so that no data is lost when performing a user log-off.

  1. Setup the script.

    1. Find the application's process name from Task Manager. For example, the process name for Microsoft Word is WINWORD.

    2. Create a new script in the NightWatchman scripts directory with the same root name as the process. By default, the NightWatchman script directory is:

      C:\Program Files\1E\NightWatchman\Scripts

      So, depending on the type of scripting language used, the script for a process calledACMEAPPis saved in this directory as:

      ACMEAPP.vbs

      or

      ACMEAPP.js

    1. If you are creating a .vbs script, copy the contents of the ScriptTemplate.txt file (located in the Scripts folder under the NightWatchman installation directory) and paste into the new file created in step 2. Replace placeholders, for example do a global search and replace <Process Name> with ACMEAPP.

  2. Gather information for the application.

    1. Use a Windows spy utility, such as Spy++ to gather information on the application windows. These will be used in the script to access the interface for the application.

      • Determine the main application class type.

      • Find the child dialog classes.

      • Retrieve information about any message boxes that may require interaction when closing the application.

    2. Determine if there are any automation objects for the application.

    3. Check for embedded applications and other processes.

      • Find any Windows that are in different processes.

      • Determine any problems related to automation objects.

  3. General script sequence.

    The following sequence is used by all the provided NightWatchman power-off scripts – as such it is a tried and tested method for safely saving open files:

    1. Find the application window.

    2. Close all child dialogs.

    3. Run expectors to help close dialogs.

    4. Save and close documents from automation objects or Initiate a close.

    5. Use expectors to handle save messages.

    6. Save and close documents from the UI using SendKeys.

    7. Wait and check that the application window closes.

Things to keep in mind

The following points should be kept in mind when developing NightWatchman power-off scripts:

  1. NightWatchman script timeouts.

    • Will the script you are writing be fast enough to complete before the NightWatchman script timeout expires?

    • Should you extend the NightWatchman script timeout value?

  2. When multiple applications of the same type are running.

    • All the child dialogs of the applications can be closed generically.

    • Be careful that applications are not switched over during closure.

  3. Be aware of application states. You should know that applications may be in different states when the attempt at closure occurs. You need to cater for these in your scripts if you want to close successfully.

    • Which windows can be open in the application?

    • What messages are displayed in different circumstances during closure?

    • Is there anything that could interrupt the sequence you are assuming in the power-off script?

Running and testing a new power-off script

The following points give indicators of how the newly developed NightWatchman script can be tested before being placed in a production environment.

  1. Test the script from the command-line.

    Before attempting to launch the script from a NightWatchman prompted power-off, test it in a stand-alone mode from a command line. To do this, start the target application with an open test document (nothing critical, just in case the closure fails) and run the power-off script.

    The majority of the functionality in the template script relies on the fact that the script helper is installed. This takes place when the NightWatchman Agent is installed, so the script cannot be tested until this is done.

    The following shows an example command line for the acmeapp.vbs script.

    Copy
    CScript acmeapp.vbs –DEBUG=7 

    The use of the–DEBUG=7switch prompts any script based on the scripttemplat.txt file to generate a debug log file, which is useful if the script fails to shut down the application.

  1. What if the script fails.

    Check the log file for the script. By default this is created in C:\temp as follows:

    NWM<scriptname>.log file

    Where <scriptname> is script. So the log file in our example is called NWMACMEAPP.log

  1. Rerun the script on a locked workstation.

    After testing the script successfully from the command-line in a basic situation, re-run the script on a locked workstation. This simplest way of doing this is to add:

    Copy
    Wscript.Sleep( 5000 ) 

    At the start of your power-off script. Then when running the script from the command-line, you have a reasonable amount of time to lock the workstation by hand before the main body of the script commences.

  2. Test the script in situ with a NightWatchman power-off.

    The final test is to have the new power-off script running alongside all the other NightWatchman power-off scripts. To do this, open and edit test documents in all the Microsoft Office applications and also have your target application open with an edited document. Then, trigger an immediate power-off from NightWatchman. This runs all NightWatchman power-off scripts enabling you to monitor their interaction and check for any immediate errors. If the power-off is successful, on restarting the machine, check all test documents have been saved correctly.

Write power-off scripts

Setting the script running order

In Windows 1E NightWatchman Agent scripting reference, we discussed the process you should go through to develop a NightWatchman power-off script. This section describes the mechanics of NightWatchman scripts and how these can be put together to implement a new power-off script.

The functionality of the NightWatchman service can be extended by creating additional power-off scripts. Administrators can write Windows scripts in VBScript to handle the intelligent shutdown of applications so that no data is lost when performing a user log-off.

During power-off, the scripts will attempt to save current versions of all open and edited files. Any open dialogs in the currently running applications are also handled in order to execute the closure of the application in a safe way. At next log-on, the user will be notified that backups have been made and given the option of accepting or rejecting these.

To run correctly, scripts must be saved in the NightWatchman scripts directory, immediately below the NightWatchman installation directory:

C:\Program Files\1E\NightWatchman\Scripts

If all the scripts are present in the root of the NightWatchman script directory, they will be run in an arbitrary order. You can control the order in which the scripts can be run, by creating specifically named subfolders in this directory and placing scripts in the sub directories.

NightWatchman supports ten sub directories named Sub0 up to Sub9. The scripts in Sub0 are run first then the ones in Sub1 and so on up to Sub9. After the scripts in the sub directories have been run, NightWatchman will then run any scripts in the main scripts directory.

Writing NightWatchman scripts

NightWatchman comes with pre-defined scripts that handle the following products: Microsoft Outlook, Microsoft Word, Microsoft PowerPoint, Microsoft Excel and Notepad. To handle other applications you can either contact 1E or write your own scripts – see NightWatchman helper APIs.

How the script phase works

The power-off script phase of the NightWatchman system contains the following steps:

  • NightWatchman compiles a list of all the applications running.

  • For each application found, it searches for a script with the same base name as the application executable.

  • NightWatchman then executes this script to handle the closing of the application.

For example, a user is logged on when NightWatchman initiates a power-off, and that user has been editing a Microsoft Word document. NightWatchman first detects that Microsoft Word is running, the executable being winword.exe.

It then searches the NightWatchman scripts directory for winword.js. If it fails to find this, it will then search for winword.vbs. If it finds this script, it will then execute it to handle the closing of Microsoft Word.

It is also possible to write scripts that are version specific. For example, winword.900.53.9.0.vbs

A script helper

In order to perform certain operations and to simplify the creation of application power-off scripts, the NightWatchman installation includes a script helper object called NWMScriptHelper.ocx. This is an ActiveX scripting object intended to be instantiated from within a Windows Scripting Host file. For detailed information on NightWatchman scripting see NightWatchman helper APIs.

The helper object provides methods that can be called from within a script. These methods cover the following general areas:

  • To remove the delays that are sometimes explicitly added to scripts when waiting to ensure a particular window appears. Scripts can now use the helper to wait for a window to appear or disappear; see WaitForWindow and WaitWindowGone .

  • Scripts can start working on an application in an indeterminate state – the helper can Cancel, Close or OK dialogs. See CloseActiveAppDialogs .

  • The scripts can be very much more window aware when they use the helper. The helper ensures that the process being controlled contains the active window; see ActivateApp , GetAccItem , SelectAccItem and SelectSubItem .

  • The helper enables regular expressions to be used in power-off scripts for matching window names to allow more generalized matching with in the fields. See FindWindowLike .

  • The helper allows actions to be performed in response to expected events without a lot of difficult scripting. see ExpectWindow .

  • The helper supports the automatic creation of backup names. See MakeNWMFilename .

  • Other functions have been added which may be part of the WScript.Shell object or the FileScriptingObject. This will allow calls to be logged consistently.

An annotated power-off script

An annotated script for Notepad

This section provides an annotated guide for a simple script to handle Notepad.exe shutdowns. The problems dealt with are general ones, though obviously the shutdown procedures for some applications may be far more complex than the ones used for Notepad.

  1. Error checking.

    • All scripts should include an error checking section to catch errors and exit the script gracefully. As a convention, this is usually placed at the start of the power-off scripts.

      Copy
      Sub ThrowError (Number, Description) 
         ObjApp = "" 
         WScript.Echo WScript.ScriptName + " " + CStr(number) + " " + description 
         NwmScript.Log WScript.ScriptName + " " + CStr(number) + " " + description 
         WScript.Quit number
      End Sub
  2. The main script body.

    • The main body of the script deals with manipulating the application in whatever state it may be in during a power-off.

  3. Initiating variables.

    • The first task is to initialize the variables used in the remainder of the script.

      Copy
      hwnd = 0 '** window handle ** 
      debugx = 0
  4. Command-line arguments.

    • Two arguments are passed in by the service when the script is started – the handle to the window and a debug level parameter – this allows debugging to be enabled globally without changing the scripts.

      Copy
      Set objArgs = WScript.Arguments
      For i = 0 To objArgs.Count – 1
         If objArgs = "-DEBUG" Then 
            debugx = 1 
         ElseIf UCase(Left(objArgs, 6)) = "-HWND=" Then 
            hWnd = Clng("&H" + right(objArgs, 8))
         Else 
            WScript.Echo "Usage: " + WScript.ScriptName + " [-hWnd=0xnnnnn] [-DEBUG]" 
            WSCript.Quit -2
         End If
      Next
  5. Initializing the script helper object.

    • Get the Script Helper object and initialize a few properties. Debug logging is normally off but can be turned on to help with debugging new scripts. Each call to the helper will be logged with its input parameters and the returned value. The backup directory is set to the user's profile application data area.

      Copy
      '** get the NightWatchman script helper object **
      Set NwmScript = WScript.CreateObject("NWMSCRIPT.NWMScriptHelperCtrl.2") 
      NwmScript.logFileName = "c:\temp\nwmNotepad.log" 
      NwmScript.debug = debugx  '** can increase this to 3 for max logging ** 
      NwmScript.TimeoutSecs = 2 
      dumpdir = NwmScript.BackupDirectory
  6. Changing the default NightWatchman backup directory.

    • The NwmScript.BackupDirectory property returns the default location where the NightWatchman backups are saved. This is set by NightWatchman to:

      Copy
      C:\documents and settings\<username>\application data\1e\NightWatchman, 

      where <username> is current user's logon name. If you want to change the save location for NightWatchman backups, change the code that sets the dumpdir variable. For example, to change the dumpdir variable to point to another location:

      Copy
      dumpdir = "u:\temp"
    • This example makes use of a user mapped drive u:. You can set this to any mapped drive the user may have set up on his computer. The advantage of using a user mapped drive is that they will be able to keep their NightWatchman backup files separate from all other users.

  7. Code to help with testing.

    • The following line is only used when writing/testing the scripts using "cscript.exe" . Normally hWnd is passed in by the service so there is no possibility of interacting with the wrong window.

      Copy
      if hWnd = 0 Then hWnd = NwmScript.FindWindowLike ( 0, 0, "Notepad", "" )
      if hWnd = 0 Then ThrowError -1, "No Window" 
  8. Getting the application process ID.

    • The NightWatchman Script Helper's ActivateApp method stores the process ID for the currently active application. This may be used subsequently to ensure that keystrokes are only sent to the application being scripted.

      Copy
      NwmScript.ActivateApp ( hWnd )
  9. Closing active application dialogs.

    • Child and popup windows make it difficult for the script to continue – this function closes dialog boxes by clicking ESC, Cancel, Close or OK if that is the only option.

      Copy
      NwmScript.CloseActiveAppDialogs ( "Notepad" )
  10. Getting the currently open filename.

    • For Notepad, the filename is extracted from the window caption.

      Copy
      '** Get filename from window title ** 
      WndwName=NwmScript.GetWindowText ( hWnd ) 
      WScript.Echo ( WndwName ) 
      FileName = Replace( WndwName, " - Notepad", "" )
  11. Attempting to close the application.

    • Try and close the application by typing Alt-F4. If the application contains unsaved data, the popup window Do you want to save changes will appear. We cancel this for now by sending ESC.

      Copy
      '** find out if it contains unsaved data ** 
      ExpectId = NwmScript.ExpectWindow("Notepad","","{ESC}","Do you want to save the changes") 
      NwmScript.SendKeys ( "%{F4}" ) '** Alt-F, 4 (Exit) ** 
      WScript.Sleep ( 1000 )
  12. Does the open file contain unsaved data.

    • ExpectCancel returns the number of times that the expected window has been seen – this is used to decide if the file contains unsaved data.

      Copy
      UnSaved = NwmScript.ExpectCancel ( ExpectId )
      if UnSaved > 0 Then
  13. Handling the Save As dialog.

    • The Save As dialog box is brought up.

      Copy
      NwmScript.SendKeys ( "%FA" ) '** Alt-F, A (Save As) ** 
      h = NwmScript.WaitForWindow ( 0, 0, "", "Save As" )
      if h > 0 Then 
  14. Creating a new file name.

    • The Script Helper creates a new filename using the input name as a base. The helper also makes sure that this file does not already exist as this could cause failures later. The extension and path parameters are optional but the file existence check cannot be performed without these.

      Copy
      NewName = NwmScript.MakeNWMFilename ( FileName, ".txt", dumpdir ) 

      This new filename is sent to the Save As dialog.

      Copy
            NwmScript.SendKeys ( "(" + dumpdir + NewName + "){WAIT_300}%S" ) 
            WScript.Echo " Saving to " + dumpdir + NewName
         end if
      end if
  15. Closing the application.

    • Notepad is closed.

      Copy
      NwmScript.SendKeys ( "%{F4}" ) '** Alt-F, 4 (Exit) ** 
      WScript.Echo " Closing"
  16. Tidying up the environment.

    • Clean up. This section should be common to all scripts.

      Copy
      WScript.Echo "Script Complete" 
      WScript.Quit 0

The NightWatchman script helper reference

Method and property categories

This section details the methods that are available in the NightWatchman NWMScriptHelper.ocx. These methods are available for use within a power-off script once an instance of the NWMScriptHelper is created. To do this, call the following code from within your script:

Copy
WScript.CreateObject("NWMSCRIPT.NWMScriptHelperCtrl.2")

Application methods

These methods provide access to currently running applications.

  • ActivateApp – activates the specified application window.

  • CloseActiveAppDialogs – closes active dialogs in the specified application.

  • CloseActiveAppDialogsLike – closes active dialogs, like the specified class, the specified application may have open, by selecting the Cancel and Close buttons.

  • GetActiveObject – creates an application object for an application with an application scripting class.

Window methods

These methods allow you to retrieve and set properties for windows open in the currently running application, refer to NightWatchman helper APIs for details.

  • ExpectWindow: Waits for a window matching the specified search string or title.

  • FindInvisibleWindowLike: Allows you to specify a search string to find an application window that is hidden. This is similar to the Windows API FindWindow except that it can use regular expressions for the search strings.

  • FindWindowLike: Finds a window using a specified search string.

  • GetAccItem: Retrieves the value of a specified item in the active window.

  • GetWindowText: Gets the title of the specified window.

  • SelectAccItem: Makes the specified item active.

  • SelectSubItem > : Selects the specified sub item in the active window.

  • SetActiveWindow: Makes the specified window active.

  • WaitForWindow: Waits for the specified window to be created.

  • WaitWindowGone: Waits for the specified window to close.

  • ClickButton: Performs the action of the mouse clicking the specified dialog button.

  • ClickMouse: Performs the action of clicking the specified mouse button.

  • SendKeys: Sends keystrokes to the "Top Window" of the active application.

  • SendKeysToWindow: Sends keystrokes the "Top Window" of the application containing the specified Window.

  • SendKeysToDialog: Sends Keystrokes to the specified window.

Save file environment methods

These methods enable aspects of the applications open file environment to be utilized within the power-off script.

  • GetCmdLine – gets the command line path for the running application.

  • GetCurrDir – returns the current directory for the running application.

  • GetEnvVar – returns the value for the specified environment variable.

File methods

These methods provide file specific functionality.

  • CopyFile – copies a file to a specified location.

  • GetFullPath – gets the full path for the specified file.

  • MakeNWMFilename – creates a filename for a NightWatchman saved file.

  • MoveFile – moves a file to a specified location.

NightWatchman methods and properties

This method defines an interface for interacting with NightWatchman.

Methods

  • WriteToBackupList – outputs the name of a backed-up file to the log file so it can be viewed by the user from the NightWatchman Backup dialog.

Properties

  • PowerdownAction – this property allows you to query the power down action from within the script so that you can choose different execution paths based on the final state of the machine

Script methods and properties

The following properties and methods define settings for controlling and debugging the NightWatchman scripts.

Methods

  • Log – outputs a string to the scripts log file.

  • BackupDirectory – returns the user specific backup directory determined by NightWatchman.

The BackupDirectory is fixed so that files backed up are saved to the logged on user's profile.

Properties

Refer to NightWatchman scripting properties for the following properties.

  • debug: Specifies the level of debugging output to the log file.

  • LogFileName: Sets the location of the scripts log file.

  • TimeoutSecs: Sets the timeout for wait operations.