Improve RIS deployment scripts via environment variables

Environment variables can make RIS deployment scripts more dynamic.

This Content Component encountered an error

The default RIS deployment script can be easily modified in a way that will provide you with a more custom installation. You can make the deployment process better for your organization's needs, simply by changing various values or adding commands to the script.

But as powerful as these modifications can be, sometimes you need more flexibility than what you can get from a static script. Environment variables allow you to make deployment scripts act in a more dynamic manner. This article will explain what environment variables are and will show you how to use them.

Here is a sample of the default installation script that you can use as a reference:

 [data] floppyless = "1" msdosinitiated = "1" OriSrc = "\\%SERVERNAME%\RemInst\%INSTALLPATH%\%MACHINETYPE%" OriTyp = "4" LocalSourceOnCD = 1 DisableAdminAccountOnDomainJoin = 1 [SetupData] OsLoadOptions = "/noguiboot /fastdetect" SetupSourceDevice = "\Device\LanmanRedirector\%SERVERNAME%\RemInst\%INSTALLPATH%" [Unattended] OemPreinstall = no FileSystem = LeaveAlone ExtendOEMPartition = 0 TargetPath = \WINDOWS OemSkipEula = yes InstallFilesPath = "\\%SERVERNAME%\RemInst\%INSTALLPATH%\%MACHINETYPE%" LegacyNIC = 1 [UserData] FullName = "%USERFIRSTNAME% %USERLASTNAME%" OrgName = "%ORGNAME%" ComputerName = %MACHINENAME% [GuiUnattended] OemSkipWelcome = 1 OemSkipRegional = 1 TimeZone = %TIMEZONE% AdminPassword = "*" [Display] BitsPerPel = 16 XResolution = 800 YResolution = 600 VRefresh = 60 [Networking] [NetServices] MS_Server=params.MS_PSched [Identification] JoinDomain = %MACHINEDOMAIN% DoOldStyleDomainJoin = Yes [RemoteInstall] Repartition = Yes UseWholeDisk = Yes [OSChooser] Description = "Windows Professional" Help = "This will install Windows Professional in a standard configuration." LaunchFile = "%INSTALLPATH%\%MACHINETYPE%\templates\" ImageType = "Flat"

By now you should be familiar with the default script and the commands it contains. You've already seen that most of the commands in the script consist of a setting name, an equal sign and a value. The values are usually hard-coded. For example, the [Display] section contains a line of code that sets BitsPerPel to 16. In this command, 16 is a hard-coded value. Each time the script is run, BitsPerPel will be set to 16. It will never be anything else, unless an administrator manually modifies the script.

However, some lines in the script do not use literal values. For example, the first line in the [UserData] section reads:


In this case, the script is not assigning FullName a literal value; instead, the command links FullName to an environment variable (or, in this case, two environment variables). For those of you who haven't done much scripting in Windows, Windows considers text to be a variable if it has a percent sign on each side of it. Some of the other variables used in the default script are:

Environment variables are used to feed the script information that is provided (or calculated) elsewhere. For example, let's go back to the FullName = "%USERFIRSTNAME% %USERLASTNAME%" command. In this command, there's no reason you couldn't replace the environment variables with literal values. If you did, the command would look something like this:

FullName = "Brien Posey"

But hard-coding a user name into the installation script wouldn't usually be a good idea, because every system that was set up with the script would be assigned the same user name. Some organizations have a policy of just entering the organization's name in place of a user name. If your company has a similar policy, it's fine if you want to replace the environment variables with a hard-coded name. I was just using the FullName option as an example. You can use either an environment variable or a literal value for any of the commands in the entire script (with the exception of section headers).

Environment variables must be assigned a value before they're considered to be valid. That being the case, you might be wondering where the environment variables in the default script are assigned their values. Unfortunately, there is no quick answer to this question.

The script that we have been working with so far is not a standalone file. When a workstation performs a PXE boot and attaches to your RIS server, the workstation opens a watered-down, text-only Web browser. If you are looking at the workstation's screen, you'd never even know that it's running a Web browser because there's no user interface. Even so, RIS uses this Web browser to open a series of HTML files. These HTML files lead the administrator through the Windows deployment process.

For some reason, Microsoft has tried to obscure the fact that the RIS client experience is HTML-based. In fact, the HTML files do not use the HTML or HTM extensions that we are all used to seeing. Instead, these files use a .OSC extension. Even so, they contain fully customizable HTML code. If you do decide to customize your OSC files though, you should make a backup first. You must also avoid making any changes that can not be displayed in a text-only browser.

When a client initially attaches to the RIS server, the server opens a file named Welcome.osc. This file, as well as most of the other .osc files, is located in the \RemoteInstall\OSChooser\English folder. This is what the file looks like:

 <OSCML> <META KEY=ENTER HREF="LOGIN"> <META KEY=F3 ACTION="REBOOT"> <META KEY=ESC HREF="LOGIN"> <META KEY=F1 HREF="LOGIN"> <TITLE> Client Installation Wizard Welcome</TITLE> <FOOTER> [ENTER] continue </FOOTER> <BODY left=5 right=75> <BR> <BR> <BR> Welcome to the Client Installation wizard. This wizard helps you quickly and easily set up anew operating system on your computer. You can also use this wizard to keep your computerup-to-date and to troubleshoot computer hardware problems. <BR> <BR> In the wizard, you are asked to use a valid user name, password, and domain name to log on to the network. If you do not have this information, contact your network administrator before continuing. </BODY> </OSCML>

This particular file doesn't really do much other than display some welcome text and give you a choice of either pressing Enter to continue or F3 to reboot.

The second line in the file directs the script to load the LOGIN file when the Administrator presses Enter. Obviously, you don't want just anyone to be able to boot up a new machine and have Windows be automatically installed on it, since that could cause all kinds of problems. Employees could bring in their own PCs, and use the RIS server to set them up as a way of stealing software licenses.

Of course the SIDs that are assigned to a machine are all domain-based, so you may also have people who use RIS to set up a PC, then use that PC as a way to gain insight into your domain. Fortunately, you don't have to worry about any of that, because the LOGIN.OSC file forces an authorized user to log into the domain rather than RIS just blindly distributing the image files.

The authentication process is a standard part of RIS that you don't want to change. That being the case, I don't want to get into an exhaustive discussion of the authentication process. I do want to show you a couple of other things about the LOGIN.OSC file though. The LOGIN.OSC file is the first in the chain of OSC files to use environment variables. I therefore want to show you how those environment variables work, and how the LOGIN.OSC file calls other files. Here is the code for this file:

 <OSCML> <TITLE> Client Installation Wizard Logon</TITLE> <FOOTER> [ENTER] continue [ESC] clear [F1] help [F3] restart computer</FOOTER> <META KEY=F3 ACTION="REBOOT"> <META KEY=F1 HREF="LOGINHLP"> <META KEY=ESC HREF="LOGIN"> <META ACTION="LOGIN"> <BODY left=5 right=75> <BR> <BR> Type a valid user name, password, and domain name. You may use the Internet-style logon format (for example: <BR> <BR> <BR> <FORM ACTION="CHOICE">  &nbspUser name: <INPUT NAME="USERNAME" MAXLENGTH=255>   &nbspPassword: <INPUT NAME="*PASSWORD" TYPE=PASSWORD MAXLENGTH=20><BR> Domain name: <INPUT NAME="USERDOMAIN" VALUE=%SERVERDOMAIN% MAXLENGTH=255> <INPUT NAME="NTLMV2Enabled" VALUE=%NTLMV2Enabled% MAXLENGTH=255 type=VARIABLE> <INPUT NAME="ServerUTCFileTime" VALUE=%ServerUTCFileTime% MAXLENGTH=255 type=VARIABLE> </FORM> <BR> <BR> <BR> Press the TAB key to move between the User name, Password, and Domain name fields. <BR> <BR> You are connected to %SERVERNAME% </BODY> </OSCML>

As I discuss what this code does, I will be referring to Figure B. Figure B shows the page as it appears when viewed through Internet Explorer. This isn't exactly what the page looks like when executed through RIS, but it is close enough for educational purposes. Figure B  This is what LOGIN.OSC looks like when viewed through Internet Explorer.

Calling other files

Let's talk about some of the ways in which LOGIN.OSC calls other files. Being able to trace your way through the file structure is a key skill if you want to build customized deployment applications.

External files are called mainly in two ways: through HREFs and through form actions. HREFs are basically just the links that you see on Web pages that take you to other pages. Normally, you activate links by clicking on them. But since the RIS Web browser does not include a GUI, HREFs cannot be clicked on. Instead they have to be assigned to keys. Take a look at the following line of code:


In this line, an HREF is being assigned to the F1 key. When F1 is pressed, the LOGINHLP file is loaded.

The other primary means of navigating between files is through form actions. A form action is simple to construct. The following block of code is a form and a form action:


Although this particular block of code might look intimidating, it's actually pretty simple. HTML forms begin with the <FORM> tag and end with the </FORM> tag. You will notice that the first line in the block of code above has an action associated with the form. The value assigned to the action (in this case CHOICE) is the name of the file that will be called when the form is completed. A form is considered to be complete when the user presses Enter. In a graphical HTML environment, a form would be considered to be complete when the user clicks the Submit or OK button.

All of the lines of code in between the <form> and </form> tags are used to define form choices. I will talk about these in the next section.

Environment variables

If you look at the code between the Form tags above, you'll see there are five lines of code used to define five different choices, or points of data entry. In the code above, there are five corresponding text boxes.

Entire books have been written on HTML forms. All the possibilities cannot be covered within the confines of an article. What I do want to do is to take one of the options from the block of text above and show you how it works.


The line above starts out with Domain Name:. There's nothing special about this text; it's just the text displayed on screen. It could say anything, it doesn't even have any effect on the input field.

The next word in the line is Input. You'll notice that Input is presented as an HTML tag. This is the script's way of telling the browser that it expects the user to enter a piece of information.

Just to the right of the word Input is a block of text that reads Name="USERDOMAIN". What this line does is that whatever information the user inputs gets assigned to a variable named USERDOMAIN. USERDOMAIN is not an environment variable, but rather an HTML variable. The reason this is being used is because the form action passes the contents of all HTML variables that have been defined to the file specified by the form action tag (in this case it's the choice file).

The next part of the line is VALUE=%SERVERDOMAIN%. The Value command assigns a default value to the field. In this case, the default value will be based on the environment variable %SERVERDOMAIN%. I don't have any RIS compliant hardware at my disposal at the moment, so I was unable to test this, but from what I can tell, the %SERVERDOMAIN% environment variable is initialized by the RIS server automatically. The server obviously knows what domain it belongs to and assumes that the administrator wants to log into that domain. It therefore automatically populates the Domain Name field with the name of the domain that the RIS server belongs to.

You can see that the Domain Name field has been populated by the %SERVERNAME% variable. When this code runs for real, the variable name is replaced with the actual domain name. However, the user is free to enter a different domain name. Likewise, you can hard-code the name of a different domain directly into the Value=parameter.

The last part of the command is MAXLENGTH=255. This portion of the command simply defines the longest string of text that the user can enter as a domain name.

Now that I have shown you how environment variables are used in conjunction with OSC files, you can begin to build some custom deployment scripts of your own.

About the author: Brien M. Posey, MCSE, is a Microsoft Most Valuable Professional for his work with Windows 2000 Server, Exchange Server and IIS. He has served as CIO for a nationwide chain of hospitals and was once in charge of IT security for Fort Knox. He writes regularly for and other TechTarget sites.

More information on this topic:

This was first published in December 2006

Dig deeper on Server Hardware for Windows



Enjoy the benefits of Pro+ membership, learn more and join.



Forgot Password?

No problem! Submit your e-mail address below. We'll send you an email containing your password.

Your password has been sent to: