Windows

Creating logon scripts with KiXtart, part 1: Background and common structures

Although KiXtart is primarily used to create logon scripts, you can also use it as a general-purpose scripting tool for Windows administration. In part 1 of this series, Richard Charrington shows you how.

KiXtart is a logon script processor and enhanced scripting language for computers running Windows NT or Windows 9x in a Windows networking environment. You can use the KiXtart free-format scripting language to display information, set environment variables, start programs, connect to network drives, read or edit the registry, change the current drive and directory, and much more. Although primarily used to create logon scripts, KiXtart can also be used as a general-purpose scripting tool for Windows administration. In part 1 of this series of Daily Drill Downs, I’ll introduce you to KiXtart, highlight some of the basics, and help you get started by providing a selection of working examples.

How to get KiXtart
KiXtart is provided by Microsoft free of charge but without official support. The language has been around for a long time; I’ve been using it for well over four years.

Latest and greatest versions of KiXtart are available at:

KiXtart logon scripts

ScriptLogic

CompTrends

When you download KiXtart, you get a very comprehensive manual, amounting to some 111 pages. The manual describes in detail all the commands, macros, variables, expressions, and functions.

The logon batch file
First, I’d like to show you a batch file I use to begin the logon process:
@ECHO OFF
REM Check if on server
REM ===============================================
REM If on server, do not run logon script
REM
REM WIZMGR is an NT server application, therefore
REM does not exist on NT Workstation (or 95)
REM ===============================================

if exist %windir%\system32\wizmgr.exe goto END

:Workstation
if exist c:\logon.ini del c:\logon.ini

REM =================================================
REM Use local Kix32 if available to prevent "downloading" if dialin
REM =================================================
If exist %windir%\Kix32.exe set KiXtart=Kix32 %0\..\
If Not exist %windir%\Kix32.exe set KiXtart=%0\..\KIX32
REM =================================================

REM =================================================
REM Run pre-logon patch
%KiXtart%patch1\patch1.scr
REM =================================================

REM =================================================
%KiXtart%logon.scr
REM =================================================

REM =================================================
REM Run post-logon patch
%KiXtart%patch11\patch11.scr
REM =================================================

REM =================================================
REM If not dialing in, copy down KiXtart if new
REM version (can't copy over when in use)
REM
If errorlevel 1 goto SkipCopy
xcopy %0\..\KIX32.EXE %windir% /D /Q
xcopy %0\..\Kx*.* %windir% /D /Q
REM =================================================

:SkipCopy

:END
This batch file isn’t designed to run on a server. I prefer to make sure nothing happens to a server "behind the scenes" when someone logs on. KiXtart provides a method that allows you to check the operating system it’s running on, but it doesn’t differentiate between Windows NT Server and Workstation.

After checking that the logon script isn’t running on a server, the batch file attempts to find the KiXtart application in the user's Windows directory. If it finds the application, the batch file sets a variable to the location. If not, the variable is set to KiXtart’s location on the logon server. This is handy if the user is dialing in, because it stops having to pull the KiXtart executable across the slow dial-up line to run it. I’ve included some sample code lines for calling patches. These patches can be KiXtart scripts or other batch files. Next, the batch file runs the KiXtart script Logon.scr, followed by any patches that should be run after the standard logon script.

When you’re running a batch file during the logon process, the expression %0\..\ points to the Netlogon directory of the server that’s processing the logon—usually z:. Also, the system sets the environmental parameter %windir% to point to the directory where the Windows operating system is installed. This is standard for Windows NT and Windows 9x.

Once the KiXtart processing has finished, the batch file will copy the KiXtart files to the user's Windows directory. The check for errorlevel 1 is used to prevent the copy from happening if the user is dialing in. The errorlevel is set to the exit status of KiXtart.

This isn’t a definitive calling batch file. I’ve seen large and complicated ones where the KiXtart script is almost an afterthought, as well as shorter, simpler ones where the KiXtart application is left on the server and all the batch file does is call a KiXtart script.
Although I tend to use the extension .scr for KiXtart script files, the currently recognized extension is .kix. However, you can use either one.
Some useful macros
KiXtart has its own built-in macros. They look like variables, but they extract the relevant values every time they’re referenced. So, if you’re going to use one of these macros more than a couple of times, it’s a good idea to use the macro once, put the result in a variable, and use that variable from then on.

As I mentioned earlier, KiXtart provides a variable, @InWIN, which is set to 1 for Windows NT and 2 for Windows 9x. The drawback is that the variable doesn’t differentiate between NT Server and NT Workstation, and there’s no method for finding out what the x is in 9x. However, once you know whether it’s NT or 9x, you can then check the relevant registry key to get the true version.

You can use KiXtart to assist in network optimization on a wide area network (WAN). The variable @IPADDRESS0 will give you the user's IP address, and the variable @LSERVER provides the name of the server handling the logon process. If you record these two values, you can determine whether users are being serviced by a local server or by a server over a slow link (and take the appropriate action if it’s the latter case).

Other useful variables are:
  • @DATE: current date (YYYY/MM/DD)
  • @TIME: current time (HH:MM:SS)
  • @USERID: current user's Windows NT user ID
  • @WUSERID: current user's Windows user ID
  • @WKSTA: computer name
  • @FULLNAME: full name of user

There are over 40 macros available in the latest version of KiXtart, so I won’t list them all here.

Coping with slow connections
The slowest connection you’re likely to encounter (barring networks with major problems) is via modem. In Windows 9x, following a successful dial-up connection the dialer changes a registry key. Here's the code:
$Dialin_value=readvalue("HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\RemoteAccess","Remote Connection")

if @ERROR > 0
 ? "ERROR"
endif

if $Dialin_value=00000000
 ? "No Connection"
else
 ? "Connection Exists"
endif
I’ve introduced several new elements here, so let me break it down. Let’s start with the if....else....endif construct. It's pretty straightforward, but keep in mind that only the test for true or false can appear on the if line and that else is optional. The conditional operators are
  • <
  • >
  • =
  • <>
  • <=
  • >=

You can combine these options by using AND or OR. Many of the commands and functions return true or false depending on whether they were successful, so you can write
if command(paameter,parameter...)  code if trueelse  code if falseendif
Next, let’s look at variables. All variables in KiXtart begin with $. Typing (deciding whether the variable is a string or a number) is automatic. Variables don’t have to be declared before they can be used. You can also implicitly declare them by assigning a value to them. Note that all variables declared in this way have a global scope. Arrays are the exception; you must declare arrays using the DIM statement. There’s no limit to the number of variables you can declare and, for all practical purposes, no limit on the number of elements you can have in an array.

The third element I’ve introduced is the function readvalue. This function allows you to obtain information from the registry. It has two parameters: the key name and the value name.

Finally, I’ve introduced @ERROR, which is set by most functions. If the function completed satisfactorily, @ERROR will be 0; otherwise, @ERROR will be set to a value that best represents the type of error encountered. The manual that comes with KiXtart lists all the error codes you’re likely to encounter.

Communicating with the user
Some logon scripts are written so that the user sees nothing and just sits there waiting for the thing to finish. Some are written so that the user is fully informed about what is going on. I prefer something in between: I like to display progress at certain relevant points so that, should the script fail for whatever reason, the user will have some idea of what was happening just before it failed.

So, how do we communicate with the user?

You may have noticed a little something in the example above that I omitted in the explanation that followed. Actually, I omitted it there so that I might include it in this section.

If you’re not sure what I’m talking about, return to the example and look at what’s happening between if and else and between else and endif. Did you think that the ? at the beginning was a typo?

Hands up everyone who thinks that the ? character is the equivalent of print (just like in BASIC)? That's what I used to think. Look at the following code:
$line5="Finally, line 5"
"This is line one...."
"and this is line one" ?
"but this is line two"
? "and this is line three" ? "and this is line four." ?
$line5
This code will produce the following output:
This is line one....and this is line one
but this is line two
and this is line three
and this is line four.
Finally, line 5
If you have a string on a line without any preceding command, that string is echoed to the console. Also, the ? character can appear anywhere on the line—it’s simply a quick way of printing a carriage-return, line-feed sequence.

However, it’s pretty confusing if code is interspersed with lines consisting solely of variable and/or quoted strings. So, you can use ? at the beginning of anything you’re going to display; you use it as if it is the equivalent of print.

Another way of displaying text is to use the display function. This function displays the contents of a file, which is useful for displaying set messages. However, you may find it a bit cumbersome to have to maintain the files outside the KiXtart script.

A more complex but powerful function for displaying text messages is messagebox. As the name implies, this function is used to display a box containing a message in much the same way as most GUI applications. You have the ability to include one or more buttons, a title, and an icon. You can also obtain the value of the button clicked by the user. Here’s an example, which produces the box shown in Figure A:
$x = MessageBox("The name of this computer does not comply with the standard naming convention for PCs. If not changed, this question will be asked next time." + chr(10)+chr(10)+"Shall I change it now?", "Logon Progress",36,15)

Figure A
You can use the messagebox function to display a message box.


Although the sample code produces the nice GUI box shown in Figure A, you’ll need a crib sheet to remind you how to arrive at the last two numbers. You’ll see what I mean when you look at the syntax of this command:
MessageBox("message", "title", style, time-out)
The elements message and title are self-explanatory; style, which is optional, is the sum of the values specifying the number and type of buttons to display, the icon style to use, the identity of the default button, and the modality. Let’s take a look at the values and their meaning:

Buttons to display
Value Meaning
0 Display OK button only.
1 Display OK and Cancel buttons.
2 Display Abort, Retry, and Ignore buttons.
3 Display Yes, No, and Cancel buttons.
4 Display Yes and No buttons.
5 Display Retry and Cancel buttons.

Icon to display
Value Meaning
16 Stop symbol
32 Question mark
48 Exclamation mark
64 Information symbol

Default button (Assumed to have been clicked on expiry of the time-out)
Value Meaning
0 First button is default.
256 Second button is default.
512 Third button is default.

Modality
Value Meaning
0 Application-modal. The user must respond to the message box before continuing work in the application.
4096 System-modal. All applications are suspended until the user responds to the message box.

When adding numbers to create a final value for the argument type, use only one number from each group. If style is omitted, a default value of 0 is assumed.

The time-out element is also optional. This specifies the number of seconds that pass before the message box closes if the user doesn’t press a button. If time-out is omitted, the message box won’t close until the user presses a button.

Conclusion
In this Daily Drill Down, I’ve given you some background on KiXtart, shown you a bit of code, and discussed a few of the common structures and commands. In future drill downs, I’ll discuss more structures and commands.

Richard Charrington’s computer career began when he started working with PCs—back when they were known as microcomputers. Starting as a programmer, he worked his way up to the lofty heights of a Windows NT systems administrator, and he has done just about everything in between. Richard has been working with Windows since before it had a proper GUI and with Windows NT since it was LANManager. Now a contractor, he has slipped into script writing for Windows NT and has built some very useful auto-admin utilities.

The authors and editors have taken care in preparation of the content contained herein, but make no expressed or implied warranty of any kind and assume no responsibility for errors or omissions. No liability is assumed for any damages. Always have a verified backup before making any changes.
0 comments

Editor's Picks