JLPT
JLPT
JLPT
Abstract
This white paper focuses on implementing registry-based Group Policy for applications that you are
developing. This document begins with some details on what registry-based policy is, and when to use
it. From there, the steps to develop registry based policy are described. The appendix to this white paper
contains a full language reference to the .adm language used to deploy registry based policies.
Contents
Introduction............................................................................................ 1
Overview of Registry-Based Policy......................................................2
Policy versus Preference
.adm Files
10
10
10
12
17
18
18
20
21
Comments
21
Strings
21
CLASS
22
List of Tables
CATEGORY
23
POLICY
24
PART
27
45
EXPLAIN
46
Line Breaks
46
46
47
47
Summary...............................................................................................49
For More Information
49
27
31
35
38
40
41
45
46
47
Introduction
Description
Administrative Templates
Security Settings
Software Installation
Scripts
Folder Redirection
This document focuses on how you can implement registry-based policy for
your application. The following topics are presented:
After reading this document, you can find out more about Group Policy from the
following resources:
Windows 2000 Server Resource Kit Deployment Planning Guide and the
Windows 2000 Server Resource Kit.
Registry-based policy is the simplest and most common type of policy setting.
This type of policy is implemented using:
Registry-based policy settings are stored in any of the four Group Policy keys
listed below. These are considered the approved registry locations for policy
settings.
For computer policy settings:
HKLM\Software\Microsoft\Windows\CurrentVersion\Policies
HKCU\Software\Microsoft\Windows\CurrentVersion\Policies
Policy
present
Preference
present
Resultant behavior
No
No
Default
No
Yes
Yes
No
Yes
Yes
Note: If you disable or remove a policy, the preference will take effect
again. Preference settings are not overwritten by any policy setting in
the registry, as they use different keys for both the policy and
preference.
If you want to create available and non-available type functionality for a part
of your component, registry-based policy is an excellent choice as it will
give administrators a switch to turn functionality on or off by configuring the
policy.
Example:
Let us assume you want to control whether a certain item is displayed or
not. You may be able to create a Group Policy that either enables or
disables having this item displayed.
If the type of policy you want to create will define a set of static modes,
registry-based policy is also a good choice.
Example:
You would like to create a Group Policy that sets the language that is used
by a computer. You have a static list of the selections that an administrator
can choose from.
When the administrator enables the policy setting from the Administrative
Templates snap-in, he or she will be provided with a list of languages to
choose from.
If the type of policy you want to create requires simple input, which can be
stored in the registry as plain text from the administrator to configure the
policy, then registry-based policy is a good choice.
Example:
o
You would like to create a Group Policy to define the screensaver
or bitmap to be displayed.
o
When users enable this policy setting, they are given a text dialog
to enter the name and path of the file to be used. This information is
stored to the registry as plain text.
o
Your application checks for this information and behaves
accordingly.
Designing and
Developing RegistryBased Policy
If the policy you want to create can be configured using a simple UI and this
configuration information can be stored in the registry as plain text, you
should consider registry-based policy.
The UI controls provided by the Administrative Templates snap-in in which
your registry-based policy will be stored are:
o
CheckBox
ComboBox
DropDownList
EditText
ListBox
Static text
These controls are described in the .adm language section of this document.
Design Considerations
It is important to clearly define what aspects of your component or application
you would like to enable with Group Policy.
For example, consider the following issues:
How many policy settings will it require to control this behavior? Refer to
the section on Best Practices for User Interface Design for more
information.
What is the default behavior? What is the behavior when the policy is
enabled or disabled? How is this reflected in the UI?
Understand the UI capabilities that the .adm language offers. The .adm
language will be used to build the UI that is presented to administrators
when they configure the policy using the Group Policy snap-in.
Policy on/off. Provide a single policy setting that controls whether or not
policy is to be applied to your application at all. It should handle allowing
defaults and/or tightly managed type policy.
For example:
HKCU\Software\Policies\CoName\AppNameVersion\Settings, with the
value of Policy the data would be one of the following values: 0,1,2,3.
With 0 = No policy applied; 1 = only apply defaults; 2 = only apply
mandated policy; and 3 = apply both.
This allows the administrator to have a switch that can be used to control
the behavior of the application.
New options for a new release. Provide policy settings for all of the new
features of the application. Provide a single Group Policy for all of the new
features, as well as a policy for each logical grouping of new features. A
policy should also be considered for specific features that administrators
would need to control after the new features have been enabled.
Rationale - One significant cause for upgrade delays in corporate
environments is the administrators inability to rollout the new version of an
application without overwhelming users and the support staff with the new
features. Enabling policy settings in this area will allow the administrator to
control how and when users get the features. Grouping related features will
allow the administrator to prevent use (or lock-out) of a new feature set until
users have been trained.
Options that create support problems. Determine the top issues that
users have with the application and consider ways that policies could be
used to prevent the support call. This applies to both the applications
support and also to in-house corporate support centers.
Feature re-design. When a product feature is being redesigned, consider
why and if a policy could help address the reason for the re-design. For
instance, if the feature was deemed overly complex, consider creating a
Group Policy that would shield users from the more advanced functions.
Requires advanced knowledge of the application. If there are
complicated or more advanced settings that the typical user does not
normally need to know about, use Group Policy to give the administrator
the ability to control access to the settings.
Data population. Use policy to populate data for your application. For
example, a phone dialer could use policy to provide the administrator with the
ability to either default and/or mandate certain items in the phone directory.
Home market issues. Group Policy settings are not just for the corporate
environment. Consider issues like limiting functions for different user skills
or feature levels for home users sharing the same computer (dad, mom, 3
to 10 year olds, 11 to 21 year olds, and so on).
o
Do nothing. In this case, the user clicks My Network Places and nothing is
displayed. The user will assume something is wrong and call the helpdesk.
This would be a poor design option. Correctly creating and using Group
Policy should reduce IT calls not increase them.
Create an error message. In this case, the user clicks My Network Places
and an error message is displayed saying: This has been disabled by your
administrator. The user will call the administrator to ask why this feature
has been disabled. Again this is not recommended.
Disable the UI. A disabled (grayed-out) UI feature typically implies that
there is a way to enable the UI. The user will likely spend a lot of time trying
to get this feature to work. In the end, they will either give up frustrated or
call the helpdesk.
Hide the UI feature. If you choose to hide the UI, the user will generally not
recognize that anything is wrong. This is the preferred choice for Group
Policy settings.
Note: You should treat the .adm files that ship in the operating system
as read only. These files will be updated from time to time in service
packs and in the future releases of the product. If you want to
customize these files, you should make a copy and save them using a
different filename.
You will want to determine if there are any policies similar to the ones you
would like to create. Looking for similar policies will provide the following:
When you create the specification document for your component, you should
make sure to include all this type of information.
Best Practices for Developing Registry Based Policy Settings
For the design of your policy, consider the following issues:
Try not to make a single policy to control all aspects of your component.
Group Policy is easier to implement and use if you have several smaller
policies. This approach gives the user more flexibility.
Your policy should have associated behavior for each of the following three
possible states:
o
Enabled should turn on the behavior indicated by the policy
name.
o
You should aim to have an associated policy for each user preference in
your application.
To hide settings and options that users may waste time setting and
unsetting.
To hide or disable a UI that can lead users into a situation in which they
must call the help desk for support.
For all your application settingsbe selective about the features you would
like to enable or disable.
If you do not intend to provide support for the policy setting. Treat each
policy as a feature that needs to be tested, validated, and supported.
When Group Policy names get localized to foreign languages, they typically
require additional characters. Therefore, we recommend that if you are
using English to name your Group Policy, you limit it to 49 characters. (This
allows your title to grow by 33 percent during localization without causing
any truncation issues when displayed.
Do not try to supplement your Group Policy title in the UI with a TIP text that
can be displayed in the UI using the TEXT Part Type provided by the .adm
language.
The following is a template that you may want to use to layout the Explain text.
You will want to include the following items (listed in order):
1.
2.
A one or two line description of the feature that the policy affects.
3.
4.
5.
6.
7.
Any notes or interactions that this policy has with other settings.
The following is an example of Explain text from the System.adm file that is
included in Windows 2000 Server:
The policy displayed is: Administrative Templates\User
Settings\Desktop\Active Desktop\Active Desktop Wallpaper.
Specifies the desktop background ("wallpaper")
displayed on all users' desktops.
This policy lets you specify the wallpaper on users'
desktops and prevents users from changing the image
or its presentation. The wallpaper you specify can
be stored in a bitmap (*.bmp), JPEG (*.jpg), or HTML
(*.htm, *.html) file.
To use this policy, type the fully-qualified path
and name of the file that stores the wallpaper
image. You can type a local path, such as
C:\Winnt\Logo.bmp or a UNC path, such as
\\Server\Share\Logo.bmp.
If the specified file is not available when the user
logs on, no wallpaper is displayed. Users cannot
specify alternate wallpaper.
Registry keys used for your policy setting must live in one of
the policy keys:
i. HKCU\Software\Policies
(preferred location)
ii. HKLM\Software\Policies
(preferred location)
iii. HKCU\Software\Microsoft\Windows\CurrentVersion\Pol
icies
iv. HKLM\Software\Microsoft\Windows\CurrentVersion\Pol
icies
The folder in which your registry keys are created under these
policy keys is up to you. We recommend that you mimic the
4) Select values that can be assigned to these registry keys that you
selected in Step 2.
You will want to choose an appropriate registry value for each of these
states that your code will look for under the key you selected in Step 2.
The Not Configured state should not write any value to the
registry.
For the actual keys that will be used, the only types of data
that can be stored to them are:
i. REG_DWORD
ii. REG_SZ
iii. REG_EXPAND_SZ
5) Modify your component to check the policy key for the registry key and
associated value(s) that you selected to be used for your policy. In the
case where you have a policy and preference:
Read the policy value first, and then if not found, read the
preference. (Policy always takes priority)
Use the standard registry functions to read both the policy and the
preference.
Consider the sample code below to perform this lookup for you.
#define PREFERENCE_KEY
TEXT(Software\\Microsoft\\Windows\\CurrentVersion\\
Explorer)
#define POLICY_KEY
TEXT(Software\\Policies\\Microsoft\\Windows\\Explor
er)
DWORD ReadValue (LPTSTR lpValueName, DWORD
dwDefault)
{
HKEY hKey;
LONG lResult;
DWORD dwValue, dwSize = sizeof(dwValue);
// First, check for a policy
lResult = RegOpenKeyEx (HKEY_CURRENT_USER,
POLICY_KEY, 0,
KEY_READ, &hKey);
if (lResult == ERROR_SUCCESS)
{
lResult = RegQueryValueEx (hKey,
lpValueName, 0, &dwType,
(LPBYTE)
&dwValue, &dwSize);
RegCloseKey (hKey);
}
// Exit now if a policy value was found
if (lResult == ERROR_SUCCESS)
{
return dwValue;
}
// Second, check for a preference
lResult = RegOpenKeyEx (HKEY_CURRENT_USER,
PREFERENCE_KEY, 0,
KEY_READ, &hKey);
if (lResult == ERROR_SUCCESS)
{
dwSize = lResult = RegQueryValueEx (hKey,
lpValueName, 0,
&dwType, (LPBYTE)
&dwValue, &dwSize);
RegCloseKey (hKey);
}
6) Make sure that the UI for your component adheres to any policies that
you create. If your policy removes or disables functionality this must be
reflected in the UI. Refer to more details in the Developers Role in
Developing Registry-Based Policy for UI behavior guidelines.
7) The component which you are policy enabling should check the
appropriate policy keys when your component starts and also during a
policy refresh. Policy is refreshed periodically and the assigned policy
settings could change. Therefore, if you have a policy setting that
changes the user interface, it is even more important for you to monitor
when a policy refresh occurs so you can refresh the display.
For example:
You create a policy that removes the Find command from a menu
in your application. When this policy is enabled, a registry key is set
to indicate that the Find command should not be available.
When your application starts it should check for this key, and if so
make the Find command unavailable.
But what if the user is already logged on, and has the application
open? In this scenario, when policy is refreshed, you want this
change to take effect immediately and not require the user to close
and reopen the application. By watching for a policy refresh, and
refreshing the display, you can prevent this problem.
You can implement this using two different methods. The first is to use the
RegisterGPNotification API to allow you to be notified when Group
Policy has been changed. To use RegisterGPNotification, an
application will more than likely do this from a background thread. A code
sample is provided below:
//
case WM_SETTINGCHANGE:
if (!lstrcmpi ((LPTSTR)lParam, TEXT("Policy"))) {
if (wParam) {
If security is important to you, you should try to implement registrybased policy at the lowest level possible. If you can make your APIs
policy aware, it will be very difficult for the policy to be defeated. If you
implement the policy at a higher level, possibly just at the UI level, a
user can create an application that will bypass your policy.
6) Test your new policies individually first. Then test how each policy
interacts with other policies that are similar, or affecting the component
that your new policy affects.
Example: You create a policy to configure the wallpaper that will be
displayed on your clients desktops. If you check the current list of
policy settings that ship with Windows 2000, you will find that there
are other wallpaper policies that already exist. In this scenario, you
should test how these policies interact. Any issues that arise need
to be addressed or documented in the Explain text.
Best Practice:
Testing should ensure that the UI is policy aware. If the UI is not aware
of the policy, the user experience will be confusing and cause confusion
for the end user.
For example: If your policy restricts access to a certain item in your
component, then all access to this component and its configuration
should not be available in the UI. Some of the possible ways to achieve
this are:
a. Removing the item completely visually.
b. Grey-out the item and disable it.
Appendix A: .adm
Language Reference
7) If your .adm file was successfully loaded, you will be returned to the
dialog that you saw in Step 4. In this case click on Close. Your policy
template has been added successfully. Skip all the steps below.
8) If your .adm file was not successfully loaded, you will be presented with
a dialog displaying the errors that occurred during the loading of .adm.
At this point, make a note of the errors that were found. Click on
OK.
You will be returned to the dialog that you saw during Step 4.
Although your .adm file was not successfully loaded, it will still
appear in the list of .adm files loaded.
Click on Close.
You are now back to the Group Policy snap-in. At this point, edit
your .adm file and correct any problems. Then repeat this process
again starting from Step 2, to try to load your .adm template again.
Once you have policy enabled your application to use registry-based policy, you
need to create a method for a local administrator or domain administrator to enable
and configure your policy setting. All registry-based policy settings appear and are
configured using the Administrative Templates snap-in in the Group Policy Editor
(GPE).
You must create a text file that describes your policy settings using the .adm
language for your policy to be available in the GPE. The .adm language provides a
framework language.
Once an .adm file is created to detail your policies, an administrator can add this
template to the Administrative Templates snap-in and the policies will appear in the
UI. Multiple .adm files can be loaded in the Administrative Templates snap-in at the
same time. By default with Windows 2000 or higher, the following .adm files are
already loaded:
System.adm
Conf.adm
Inetres.adm
This sample .adm code allows you to configure a policy called Disable Task
Manager, which appears in the Group Policy Editor namespace: User
Configuration\Administrative Templates\Desktop Settings.
This policy achieves the following:
If you enable this policy it will create a registry key called DisableTasMgr
and set its value to 1.
If you disable this policy it will create a registry key called DisableTasMgr
and set its value to 0.
In both cases the DisableTasMgr key will be created below
HKCU\Software\Policies\System
This sample gives you a very basic example of what you can do with .adm files. The
following sections of this document walk you through more details of the .adm
language.
contain zero or more parts. The .adm language includes the following components:
Comments
Strings
CLASS
CATEGORY
POLICY
PART
ITEMLIST
ACTIONLIST
Comments
There are two methods that you may use to add comments to an .adm file. You can
precede the comment either with a semicolon (;) or two forward slashes (//). Or you
can place comments at the end of any valid line.
Strings
To add strings to an .adm file, precede the text with two exclamation points (!!). At
the end of your .adm file, all strings must be defined in the [strings] section of
the .adm file. The strings must be enclosed in quotes. Optionally, you can enclose a
variable name or hard-coded string in double quotation marks.
Example:
POLICY !!LimitSize
EXPLAIN !!LimitSize_Explain
strings section
TIP1 Limit Profile Size to
[strings]
LimitSize="Limit profile size"
LimitSize_Explain="Limits the size of user profiles"
Best Practice:
It is a best practice to place all strings used in your .adm file in the [strings]
section of the .adm file. This facilitates conversion of the .adm file to other
languages (localization), as you will only need to modify the [strings]
section of an .adm file to port it to different languages. Any names and
strings with spaces in them must be enclosed in double quotation marks.
CLASS
This component is used to define where your policy will appear in the Group Policy
Editor snap-in.
The first entry in the .adm file is the keyword CLASS. We use this to specify
whether the subsequent entries should be displayed under the Computer Settings
or the User Settings node of the Group Policy snap-in.
Syntax
name
This defines the name of the Class, which must be MACHINE or USER.
If the .adm file contains a Class other than the valid Classes (MACHINE or
USER), the errors are ignored when the Group Policy snap-in loads.
CLASS Example
CATEGORY
Once you have defined if your policy will appear under the Computer Settings or
User Settings node of the Group Policy snap-in using the CLASS component, you
may need to use the CATEGORY component to display a node name under which
your policy setting will be displayed in the Group Policy snap-in.
Note: To create child nodes, you may nest CATEGORY within CATEGORY.
Syntax
name
The CATEGORY name as it should appear in the Group Policy snap-in list
box. Optionally, you can enclose the variable name in double quotation
marks. Names with spaces must be enclosed by double quotation marks.
key name
This is an optional path to the registry key to use for the CATEGORY.
Do not use HKEY_LOCAL_MACHINE or HKEY_CURRENT_USER in the
registry path; the preceding CLASS statement specifies which of these
keys to use.
If you specify a key name, all child categories, policies, and parts will use
this key name, unless they specifically provide a key name of their own.
Names with spaces must be enclosed in double quotation marks.
policy definition statements
Categories can include zero or more POLICY statements. A policy
definition statement cannot appear more than once within a single
category.
CATEGORY Example
The example in Figure 2 below illustrates the use of CATEGORY and nesting.
CLASS USER
; The following categories
will be displayed
; under User settings
CATEGORY !!Desktop
KEYNAME
"Software\Policies\System"
; <INSERT POLICIES HERE>
CATEGORY !!InternalApps
KEYNAME
"Software\Policies\InternalApps"
; <INSERT POLICIES HERE>
END CATEGORY
END CATEGORY
[strings]
Desktop="Desktop Settings"
InternalApps="Line of Business Apps settings"
Keywords
KEYNAME
CATEGORY
POLICY
END
Note: If you have a CATEGORY defined with a default KEYNAME in it, and the same category is
found again later in the .adm file, that same default KEYNAME is still in effect. This means it is
possible that you could get an error message about KEYNAME being defined twice, when it was
actually just defined in the same category earlier.
POLICY
To identify a policy that the user can modify, you use the keyword POLICY. The
policy and its associated controls are displayed in a dialog box that administrators
use to set the state of the policy. You can use multiple POLICY key names under
one KEYNAME.
The following examples in Figure 3 illustrate the syntax of POLICY.
Syntax
POLICY name
[KEYNAME key name]
EXPLAIN help string
VALUENAME value name
CLIENTEXT guid
[part definition statements]
END POLICY
name
The name of the policy as it should be displayed in the Group Policy snapin namespace.
key name
This is an optional path to the registry key to use for the category. Do not
include HKEY_LOCAL_MACHINE or HKEY_CURRENT_USER in the
registry path; the preceding CLASS statement determines which of these
keys is used.
If you specify a key name, all PART definition statements will use this key
name unless they specifically provide a key name of their own.
help string
This is the text string that is displayed in the Explain tab of the policy's
dialog box.
value name
This is the registry value to modify. Selecting the option sets the value as a
REG_DWORD of 1. Clearing the option removes the registry value. To
specify values other than the default values, use the VALUEON and
VALUEOFF statements directly following the corresponding VALUENAME
statement. These statements are specified as follows:
VALUEON on value
CLASS MACHINE
CATEGORY !!DiskQuota
KEYNAME "Software\Policies\MS\DiskQuota"
POLICY !!DQ_Enable
EXPLAIN !!DQ_Enable_Help
VALUENAME "Enable"
VALUEON NUMERIC 1
VALUEOFF NUMERIC 0
CLIENTEXT {3610eda5-77ef-11d2-8dc}
PART !!DQ_EnableTip1
END PART
END POLICY
TEXT
END CATEGORY
[strings]
DiskQuota="Disk Quotas"
DQ_Enable="Enable disk quotas"
DQ_Enable_Help="Enables and disables disk quota management"
DQ_EnableTip1="Enable disk quotas for all NTFS volumes"
KEYWORDS
KEYNAME
PART
VALUENAME
VALUEON
VALUEOFF
ACTIONLISTON
ACTIONLISTOFF
END
HELP
CLIENTEXT
POLICY
PART
You can use PART to specify various options, such as drop-down list boxes, text
boxes, and text in the lower pane of the Group Policy snap-in. See Figure 5 below.
Note:
For a simple policy where you only need to set a registry key to either 1 or 0, you
will not need to use PART. PART allow you to make the system administrator
experience richer and also collect more information from the administrator through
simple controls.
Syntax
name
Specifies the PART name as it should appear in the Group Policy snap-in.
It may optionally be enclosed by double quotation marks. Names with
spaces must be enclosed by double quotation marks.
part-type
A policy PART type. This can be one of the types shown in the
following table.
Table 3 Policy PART Types.
CHECKBOX
COMBOBOX
DROPDOWNLIST
LISTBOX
EDITTEXT
TEXT
NUMERIC
type-dependent data
This is information about the PART.
key name
This is an optional path to the registry key to use. Do not include
HKEY_LOCAL_MACHINE or HKEY_CURRENT_USER in the registry
path. If no key name is specified, the previous key name in the hierarchy is
used.
value name
Indicates the registry value to modify. Selecting this option sets the value to
a REG_DWORD of 1, and clearing the option removes the registry value. If
you want to specify values other than the default values, use the
VALUEON and VALUEOFF statements directly following the
corresponding VALUENAME statement. You specify these statements as
follows:
VALUEON on value
VALUEOFF off value
Keywords
CHECKBOX
TEXT
EDITTEXT
NUMERIC
COMBOBOX
DROPDOWNLIST
LISTBOX
END
CLIENTEXT
PART
Using the valid keywords along with the PART component allow you to add text and
various User Interface controls to the properties page belonging to the policy that
you are creating when it appears in the Group Policy editor.
Because much of the syntax is related, the next section will present a task-based
approach to writing the syntax for these PART types used to create the UI elements
above.
Using the different PART types, you can add different kinds of text and controls to
enhance your policy setting. All of these types need to be used with the PART
component defined earlier in this document.
1)TEXT
Syntax
PART tezt TEXT
END PART
text:
Text to be displayed is entered here. It can be hard-coded and placed with
quotes or you can make the string a variable by putting !! in front of the variable
name.
The following example illustrates the use of TEXT. The Disable Active Desktop
policy deactivates Active Desktop and prevents users from enabling or disabling
Active Desktop, or modifying the configuration.
POLICY !!NoActiveDesktop
KEYNAME "Software\Microsoft\Windows\CurrentVersion\Policies\Explorer"
EXPLAIN !!NoActiveDesktop_Help
VALUENAME "NoActiveDesktop"
PART !!NoActiveDesktop_Tip
END PART
TEXT
END POLICY
Taking System Administrator Text Input from the Property Page of a Policy
2) EDITTEXT
Allows the user to input alphanumeric text in an edit field. The text is set in the
registry with the REG_SZ type.
Syntax
PART tezt EDITTEXT
VALUENAME value name
END PART
text:
Text to be displayed is entered here. It can be hard-coded and placed with
quotes or you can make the string a variable by putting !! in front of the
variable name. This text will be displayed on the left side of the edit box.
value name
This indicates the registry value to which the users input entered in the Edit
Text box will be written.
The PART type, EDITTEXT, accepts the options shown in the following table.
Specifies the initial string to place in the edit field. If this option is not
specified, the field is initially empty.
MAXLEN value
Specifies the maximum length of a string. The string in the edit field
is limited to this length.
REQUIRED
Specifies that the Group Policy snap-in does not allow a policy
containing this PART to be enabled, unless a value has been entered
for this PART.
OEMCONVERT
Sets the ES_OEMCONVERT style in the edit field so that typed text
is mapped from ASCII to OEM and back. ES_OEMCONVERT
converts text entered in the edit control. The text is converted from
the Windows character set (ASCII) to the OEM character set and
then back to the Windows set. This ensures proper character
conversion when the application calls the CharToOem
<JavaScript:hhobj_1.Click()> function to convert an ASCII string in
the edit control to OEM characters. This style is most useful for edit
controls that contain file names.
KEYNAME
VALUENAME
DEFAULT
REQUIRED
MAXLENGTH
OEMCONVERT
END
EXPANDABLETEXT
CLIENTEXT
CLASS USER
CATEGORY !!DesktopLockDown
KEYNAME "Software\Policies\System"
POLICY !!Wallpaper
EXPLAIN !!Wallpaper_Explain
PART !!Wallpaper_Tip1
END PART
TEXT
PART !!Wallpaper_Filename
VALUENAME Wallpaper
MAXLEN 60
END PART
EDITTEXT
END POLICY
END CATEGORY
[strings]
DesktopLockDown="Desktop Settings"
Wallpaper="Desktop Wallpaper"
Wallpaper_Explain="Used to set the desktop wallpaper"
Wallpaper_FileName="Filename"
Wallpaper_Tip1="Specify UNC Path for selected wallpaper"
In this example, when the policy setting is enabled the text entered into the edit field
will be written to the registry key HKCU\Software\Policies\System\Wallpaper. This
text may be a maximum of 60 characters.
When this policy is Not Configured or Disabled, this key will not be written.
3) COMBOBOX
Displays a combo box. The PART type, COMBOBOX, accepts the same options as
EDITTEXT, as well as the SUGGESTIONS option, which begins a list of
suggestions to be placed in the drop-down list. SUGGESTIONS are separated with
spaces and must be enclosed by double quotation marks when a value includes
spaces. If a suggestion name includes white space, it must be enclosed in quotes.
The list ends with END SUGGESTIONS.
For example:
SUGGESTIONS
Alaska Alabama Mississippi New York
END SUGGESTIONS
KEYNAME
VALUENAME
DEFAULT
SUGGESTIONS
REQUIRED
MAXLENGTH
OEMCONVERT
END
NOSORT
EXPANDABLETEXT
CLIENTEXT
END
Displays a check box. The value is set in the registry with the REG_DWORD type.
Default Behavior:
Syntax
PART text CHECKBOX
VALUENAME value name
END PART
text:
This represents the text to be displayed on the right of the check box that
you are creating. It can be hard-coded and placed with quotes or you can
make the string a variable by putting !! in front of the variable name.
value name
Indicates the registry value to which the selected value will be written.
Selecting the option sets the value as a REG_DWORD of 1. Clearing the
option removes the registry value. To specify values other than the default
values, use the VALUEON and VALUEOFF statements directly following
the corresponding VALUENAME statement. These statements are
specified as follows:
VALUEON on value
VALUEOFF off value
When you use these statements, the behavior is modified such that if the
administrator selects the option, the value is set to on value. If the
To modify more then one registry key you can use an ACTIONLIST.
KEYNAME
VALUENAME
VALUEON
VALUEOFF
ACTIONLISTON
ACTIONLISTOFF
DEFCHECKED
CLIENTEXT
END
Displaying a Numeric List to the Administrator From Which They Need to Select
an Item From the Property Page of a Policy
If you are trying to display a list of numbers, and you would like to have your
administrator select one of the predefined numeric values, you should use a spin
control. A spin control is implemented using the PART type, NUMERIC.
1) NUMERIC
Displays an edit field with an optional spinner control (an up-down control) that
accepts a numeric value.
Default behavior:
The NUMERIC type accepts the options shown in the following table.
Specifies the initial numeric value for the edit field. If this option is not
specified, the field is initially empty.
MAX value
Specifies the maximum value for the number. The default value is
9999.
MIN value
Specifies the minimum value for the number. The default value is 0.
REQUIRED
Specifies that the Group Policy snap-in does not allow a policy
containing this PART to be enabled unless a value has been entered
for this PART.
SPIN value
TXTCONVERT
Syntax
PART text NUMERIC
VALUENAME value name
MIN xx
MAX xx
END PART
text:
This represents the text to be displayed on the right of the spin control that
you are creating. It can be hard-coded and placed with quotes or you can
make the string a variable by putting !! in front of the variable name.
value name
Indicates the registry value to which the selected value will be written.
NUMERIC Spin Control Example.
The following example in Figure 9 below illustrates implementing a spin control
using the PART type, NUMERIC.
CLASS USER
CATEGORY !!Sample
KEYNAME "Software\Policies"
POLICY !!MaxOpenDocs
EXPLAIN !!MaxOpenDocs_Help
PART !!Sessions NUMERIC REQUIRED
VALUENAME "MaxDocs"
MAX 100
MIN 1
SPIN 5
END PART
END POLICY
END CATEGORY
[strings]
!!MaxOpenDocs=The maximum number of connected users
!!MaxOpenDocs_Help=This policy settings controls the max number of
allowed connections
!!Sessions=Maximum connections
!!Sample="Desktop Settings"
KEYNAME
VALUENAME
MIN
MAX
SPIN
DEFAULT
REQUIRED
TXTCONVERT
END
CLIENTEXT
You can use this PART type to display a combo box with a drop-down style list. You
can pre-populate the list of items that are displayed in the list and the corresponding
registry value to be written for each item in the list.
DROPDOWNLIST accepts the option shown in the following table.
Specifies that the Group Policy snap-in does not allow a policy
containing this PART to be enabled unless a value has been entered for
the PART.
Syntax
PART text DROPDOWNLIST
ITEMLIST
NAME name VALUE value
..
NAME name VALUE value
END ITEMLIST
END PART
text:
This represents the text to be displayed on the right of the spin control that
you are creating. It can be hard-coded and placed with quotes or you can
make the string a variable by putting !! in front of the variable name.
name:
This is text that will be displayed in the drop-down list for a particular item.
value:
The value to be written to the specified registry key if this item is selected.
Values are assumed to be strings, unless they are preceded by NUMERIC.
The following example shows both string and numeric values:
VALUE Some value
VALUE NUMERIC 1
DROPDOWNLIST Example:
The following example in Figure 10 below illustrates creating a Drop-down list using
the PART type, DROPDOWNLIST.
CLASS USER
CATEGORY !!Sample
KEYNAME "Software\Policies\System"
POLICY !!Autorun
EXPLAIN !!Autorun_Help
PART !!Autorun_Box
DROPDOWNLIST REQUIRED
VALUENAME "NoDriveTypeAutoRun"
ITEMLIST
NAME !!Autorun_NoCD VALUE NUMERIC 181 DEFAULT
NAME !!Autorun_None VALUE NUMERIC 255
END ITEMLIST
END PART
END POLICY
END CATEGORY
[strings]
Sample="Desktop Settings"
Autorun_Box="Disable Autoplay on:"
Autorun_NoCD="CD-ROM drives"
Autorun_None="All drives"
Autorun_Help="Disables the Autoplay feature"
Autorun="Disable Autoplay"
KEYNAME
VALUENAME
REQUIRED
ITEMLIST
END
NOSORT
CLIENTEXT
2) LISTBOX
Displays a list box with Add and Remove buttons. This is the only PART type that
can be used to manage multiple values under one key. The VALUENAME option
cannot be used with the LISTBOX part type because there is no single value name
associated with this type.
LISTBOX accepts the options shown in the following table.
EXPLICITVALUE
This option makes the user specify the value data and the value
name. The list box shows two columns, one for the name and
one for the data. This option cannot be used with the
VALUEPREFIX option.
VALUEPREFIX
prefix
By default, only one column appears in the list box, and for each entry a value is
created whose name and value are the same. For instance, a name entry in the
list box creates a value called name whose data is name.
The valid keywords for LISTBOX are:
KEYNAME
VALUEPREFIX
ADDITIVE
NOSORT
Appendix B: Additional
Keywords
EXPLICITVALUE
EXPANDABLETEXT
END
CLIENTEXT
ACTIONLIST
You can use an action list to specify a set of arbitrary registry changes to make in
response to a control being set to a particular state.
Syntax
key name
This is an optional path to the registry key. Do not include
HKEY_LOCAL_MACHINE or HKEY_CURRENT_USER in the registry
path; the preceding CLASS statement defines which of these keys to use.
If no key name is specified, the previous key name in the hierarchy is used.
value name
Indicates the registry value to modify. Selecting this option sets the value to
a REG_DWORD of 1, and clearing the option removes the registry value. If
you want to specify values other than the default values, use the
VALUEON and VALUEOFF statements directly following the
corresponding VALUENAME statement. You specify these statements as
follows:
VALUEON on value
VALUEOFF off value
value
Values are treated as strings unless they are preceded by NUMERIC, as in
the following examples:
VALUE "Some value"
VALUE NUMERIC 1
ACTIONLISTOFF
ACTIONLIST Example
EXPANDABLETEXT
REQUIRED
Generates an error if the user does not enter a value when required.
For example:
PART !!MyVariable
EDITTEXT REQUIRED
VALUENAME ValueToBeChanged
END PART
MAXLEN
PART !!MyVariable
EDITTEXT
VALUENAME ValueToBeChanged
MAXLEN 4
END PART
DEFAULT
Specifies a default value. This can be used for text or numeric data.
For example:
PART !!MyVariable
EDITTEXT
DEFAULT !!MySampleText
VALUENAME ValueToBeChanged
END PART
or:
PART !!MyVariable
NUMERIC
DEFAULT 5
VALUENAME ValueToBeChanged
END PART
KEYNAME
The KEYNAME keyword is used within a CATEGORY to define which key within
the registry is modified as a result of an action here. KEYNAME should be followed
by the registry path to the key that contains the value that you want to change. Do
not specify HKEY_LOCAL_MACHINE or HKEY_CURRENT_USER because
CLASS defines that portion of the key. If the KEYNAME contains a space, you must
enclose the string in quotes.
VALUENAME
Defines the options available within a POLICY. First identify the registry value that
is to be modified as a result of using the keyword VALUENAME. For example,
VALUENAME MyFirstValue.
The following example illustrates the use of VALUENAME. The Disable Boot /
Shutdown / Logon / Logoff status messages policy prevents the display of
system status messages.
POLICY !!DisableStatusMessages
KEYNAME "Software\Microsoft\Windows\CurrentVersion\Policies\System"
EXPLAIN !!DisableStatusMessages_Help
VALUENAME "DisableStatusMessages"
END POLICY
Unless you specify otherwise, the value is written in the following format when the
user checks or clears the option:
You can specify options other than these defaults by using VALUEOFF and
VALUEON. If the option is to be selected within the lower pane of the Group Policy
snap-in, the VALUENAME needs to be within a PART scope.
CLIENTEXT
CLIENTEXT must be used within either the POLICY scope or the PART scope and
should follow the VALUENAME statement.
For example:
POLICY !!DQ_Enforce
EXPLAIN !!DQ_Enforce_Help
VALUENAME "Enforce"
CLIENTEXT {3610eda5-77ef-11d2-8dc5-00c04fa31a66}
PART !!DQ_EnforceTip1
TEXT
END PART
END POLICY
The GUID that follows the CLIENTEXT keyword is the GUID of the client-side
extension. The client-side extensions are listed in the registry under
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsNT\CurrentVersion\
Winlogon\GPExtensions.
You can use VALUEON and VALUEOFF to write specific values based on the state
of the option. You can enable this functionality by writing the .adm file as described
in the following examples:
or:
KEYNAME key name
POLICY !!MyPolicy
VALUENAME ValueToBeChanged
VALUEON 5 VALUEOFF 10
END POLICY
Behavior
The important thing to note is the policy-disabled state. The value is not written to
the registry with the value of 0; instead it is explicitly deleted. This means a
component reading the policy will not find it in the registry, and will fall back to using
the default in the code.
Example 2
In this example, the state values are explicitly defined, so when the user changes
the policy, the Administrative Templates use these values.
POLICY !!EnableSlowLinkDetect
EXPLAIN !!EnableSlowLinkDetect_Help
KEYNAME "Software\Policies\Microsoft\Windows\System"
VALUENAME "SlowLinkDetectEnabled"
VALUEON NUMERIC 1
VALUEOFF NUMERIC 0
END POLICY
Behavior
EXPLAIN
The EXPLAIN keyword is used to provide online Help text for a specific Group
Policy. In Windows 2000, each policys Properties page includes an Explain tab,
which provides details about the policy settings.
Each Group Policy that you create should include one EXPLAIN keyword, followed
by at least one space, and then the EXPLAIN string in quotes or a reference to the
Help string.
For example:
POLICY !!Pol_NoConfigCache
#if VERSION >= 3
EXPLAIN !!Pol_NoConfigCache_Help
#endif
VALUENAME "NoConfigCache"
PART !!Lbl_NoConfigCacheHelp1
END PART
END POLICY
.....
TEXT
[Strings]
Pol_NoConfigCache_Help="Prevents users from changing the\n\nautomatic
synchronization behavior at logoff."
In the preceding example, Help is offered for one of the Offline Files options. The
EXPLAIN keyword wrapped in the #if VERSION allows this .adm file to be used
with the Windows 2000 Group Policy snap-in (which is version 3).
Refer to the section Writers Role in designing Registry Based Policy for more
details.
Line Breaks
To start text on a new line or to create a line break, use this syntax:
\n = Starts a new line
\n\n = Creates a line break
The valid Operators for the Version statement number are listed in the following
table.
Signifies
> (GT)
< (LT)
== (EQ)
!= (NE)
Not equal.
>= (GTE)
Greater than or equal to. For example, a >= b means a is greater than or equal
to b.
<= (LTE)
Less than or equal to. For example, a <= b means a is less than or equal to b.
Summary
You can use the following keyboard shortcuts to navigate the Administrative
Templates namespace:
When the floating Properties page is displayed, move it out from in front of the
Group Policy snap-in window. Then click back onto one of the Policies in the results
pane. You can now use the cursor keys to navigate up and down the list. Notice that
the information in the Properties page changes. This method also works for the
Explain text. You may also use the Tab key to move back and forth between tree
pane and the results pane, while leaving the Properties page open.