Friday, February 19, 2010

Convert Registry file to ADMX Policy file

Many times we need to apply a registry file (.reg)  to our many systems (1400+), and it's a real pain ... specially that we really like using Group Policies for everything.
if it's just a few values we create an ad-hoc registry policy and set the values thru GPO, but when we have a large .REG file with a lot of settings things become a lot harder, and we have to start dancing around figuring out how to best deploy this settings.
To make things worse, after a while, we would look at the policy and trying to figure out what those registry setting meant and where they came from ... like I've said: a real Pain ...

In the past, I attempted to create an ADM file for a couple of our most common application, but I gave up due to the complexity of the ADM syntax.

Last weekend I was thinking about this again and I decided to give it another try. I did not want to use and "old" standard, so I decided to research the ADMX policies. I opened the ones I found in my systems and it seemed pretty simple to understand.
So I downloaded the ADMX samples and the schema/syntax definition from MS and got to work.

Luckily for me, the syntax is really simple, XML simple, and I quickly realized that instead of creating a new ADMX to apply the setting of my problematic .REG file, I could create a tool to parse any registry file into a corresponding ADMX policy definition.
It took me the whole weekend but by 2 AM Monday I had a functional (and much debugged) tool.

I did not had any development tool installed on my system so I decided to use good-old VBScript to write the tool. This has the added bonus that anyone can read it and update it without much requirements.

What it does
Reads a registry file (.reg) and creates the corresponding ADMX and ADML files that would allow to set the registry values detail led in the original .reg file.
in order to create the GUI definition required by the GPMC, it makes a few assumptions:
a) the "name" of the value is also used as the caption for all displays.
b) all dwords values are assigned a numeric textbox for data entry
c) all other value types are treated as strings and assigned a textbox for data entry.

Caveats
@ or (Default)
The tools will not handle correctly the "@" or unnamed valuename. This is the one that in the registry editor shows as (Default).
The reason for this is that I have not been able to find the correct way to define this in ADMX/L.

WORKAROUND: For now it's assigning the value to a "(Default)" value, but as you can see in the examples bellow, windows does not recognize this "(Default)" value as the real "(Default)" value.
I will need to find an existing ADMX that sets this kind of values and read it's XML in order to learn how it's done. OR maybe someone can let me know so I can correct the tool.

Hex, Hex(0) ...
This is another example of things that I was not able to learn from the ADMX files that I have available.
We have several cases of registry files that assing a value composed of several 2 char Hexadecimal values, but I have not find any ADMX file that applies this kind of settings to to policies.
WORKAROUND: For now, and until I can find the way to do it correctly, the script will make this hexadecimal values into a text.
I will need to find an existing ADMX that sets this kind of values and read it's XML in oder to learn how it's done. OR maybe someone can let me know so I can correct the tool.


Usage:
CSCRIPT REG_2_ADMXL.vbs registry-file language [name]

registry-file is the name and path of the registry file to be converted.
language is the language and culture to be used, ie: en-US, sp-AR, etc.
name Display Name to show in the GPO. if omited "REG_2_ADMXL Generated Policy" will be used.


The output file will be named after the .REG file (if the input is myfile.REG, the output will be myfile.ADMX and myfile.ADML.
The ADMX output file will be saved in the same folder the input .REG file is located, while the ADML output file will be saved in a subfolder of the one the .REG file is located. The subfolder will be named after the language specified.
So, if the reg file is C:\myapp\myfile.reg and the lang is en-US, then the ADMX file will be as in C:\myAPP\myfile.ADMX and the ADML file will be saved as C:\myAPP\en-US\myfile.ADMX




EXAMPLE

I converted the following .reg file into ADMX/L
Windows Registry Editor Version 5.000

[HKEY_CURRENT_USER\Software\Marianok\Myapp]
@="default value of the key"
"MyAppName"="SuperApp123"
"MyAppServer"="SomeServer"

[HKEY_CURRENT_USER\Software\Marianok\Myapp\Config]
"bottom"=dword:00000000
"left"=dword:00000000
"right"=dword:00000000
"top"=dword:00000000
"color"="red"



So I ran the following command:
CSCRIPT REG_2_ADMXL.vbs c:\temp\myregfile.reg en-us

(the last parameter basically defines the language and culture to use, in this case US English)

The tool generated 2 files c:\temp\myregfile.ADMX and c:\temp\en-us\myregfile.ADML

Once you have the ADMX and the ADML files you can use them in the Group Policy Management Console to edit your GPOs more confortably.

The following 4 images show the test GPO created from the .REG file above


Notice that the diferent registry keys (the Path) became nodes on the tree, and that the "Config" Key is correctly subordinated to the "MyApp" key.
Also notice that in order to help the people that might be using this ADMX file in the future, the tool will add a description to each one of them detailling what keys is being affected.



Here one of the values was selected.
Notice that the "@" from the .reg file was replaced with (Default).
Also notice that the tool has added a comment to each setting detailling what registry value will be affected, what was the datatype reported in the .reg file and what was the value assigned in the original .reg file.


Same for the MYAPP\CONFIG node.
Notice that there are 4 values, but only 3 are enabled (only this 3 will be applied to the targets).


In this screen you can see one being edited.
Once again you can see the description/help that was created by the tool based on the .reg file.
Also notice that the value that was assigned in the original .reg file has become the default value for the field.

This is the report from the Group Policy Management

This is a millon times more readable than the mess of registry keys and setting that the GPM would be showing if we did not have the ADMX/L files inplace.
Notice that only 3 values are listed under the CONFIG section, that it's because the fourth is still disabled.


Now, after the GPO was applied to the user/workstation, we can see the registry:


Notice the issue I was mentioing before with the (DEFAULT) valuename. There are 2 of them one without data and the other witht he data we were trying to assign.
Had I imported the registry file into this system the first one would have a value ("default value of the key"), but this is not happening.


Here is the Config folder, notice that the fourth value does not show, just as expected.


WOW, that was a long post :-) ... sorry, but I'm really exited about this work :-)
if you want it, feel free to download it from my site

24 comments:

marianok said...

Also available on Technet: http://gallery.technet.microsoft.com/ScriptCenter/en-us/8c703a2e-4685-4093-a1fc-dec107c53d13

marianok said...

Additional comments:

HKU or HKEY_USERS
The ADMX definition allows you to set policies for Users (Current User, actually) and/or Computers, this does not include the HKU or the HKEY_USERS.

WORKAROUND: The script will treat any HKU policy as a HKCU (it will clean any named user defined as part of the HKU).

Thanks a lot to JimmyRolaff in the MSDN site for reporting this issue.

marianok said...

Regarding the use of HKEY_USERS\.DEFAULT, let me clarify one thing so we are all in the same page.
Unlike common belief, the .DEFAULT subkey is not the “default settings for all users without a profile”; the .DEFAULT key is actually the key for the “Local System” Account.

In other words, HKEY_USERS \.DEFAULT is just an alias for HKEY_USERS\S-1-5-18.
(see http://blogs.msdn.com/oldnewthing/archive/2007/03/02/1786493.aspx, http://www.msfn.org/board/topic/122382-hkey-usersdefault-help/ and http://social.msdn.microsoft.com/Forums/en-US/windowscompatibility/thread/f5125b7a-d5e4-4a7b-a9b6-513c5c2e430d )

So, I have good news and bad news.

The GOOD news: If you are actually trying to make some settings for all users, then the tool should work perfectly for you (as explained before, the tool will convert the HKU\.DEFAULT into HKCU)
i.e. if you have a setting being applied to for HKEY_USERS\.DEFAULT\Software the setting will be applied to for HKEY_CURRENT_USER\Software

The Bad news: If you are really trying to settings for the “Local system” account, and only that account, then I do not believe that you can do that thru GPO.

Jordan said...

awesome job! just used it and worked wonderfully. thanks so much for sharing.

marianok said...

I'm glad you like it !

Anonymous said...

God bless you, you are a life saviour.

Asier Padilla said...

Thanks, very useful.

Ronald J. de Vries said...
This comment has been removed by the author.
Ronald J. de Vries said...
This comment has been removed by the author.
Ronald J. de Vries said...

I can not import a adml/x file. Windows only accept adm files.

It's on a Windows 2008 Server

What is it that I do wrong? :)

marianok said...

Dear Ronald,
You do not need to import the admx/L, just copy it where the rest of the ADMX/L files are (Generally in \\your_domain_name\SYSVOL\your_domain_name\Policies\PolicyDefinitions\) and restart the GPMC it will pick it up inmediatelly.

I hope this helps, and sorry for the delayed answer.

Ronald J. de Vries said...

Thanks marianok! I will try it tomorrow. This would save me a lot of time!

Ronald J. de Vries said...

arianok I've importerd the template. All values are disabled and I can't figure out way.
Can you please help me ones again please? :)
Thanks!

ANIL CHAUHN said...

Hi,
I made a folder in c:\Myapp. Copied the .vbs script file and a reg file (Myreg.reg). After running the script no admx/adml files where created. I am testing on a xp prof sp3 laptop before transferring to server 2008. Can you please help and guide me, I am new to group policy deployment.

ANIL CHAUHN said...

Hi Again,
Sorry!I got it now...
Thanks for sharing.

Arthur said...

I am quoting the specific part from the sheet “AdministrativeTemplate” from cell G385, emphasis mine:

“_Registry policy_ allows an administrator to configure registry settings of any type. /This policy differs significantly from Administrative Templates policy/, which limits registry options and requires templatization of all settings. This policy can be used in conjunction with Security Settings\Registry policy, which allows an administrator to define access permissions and audit settings for registry keys. _/Computer policy/ registry settings that target the HKEY_CURRENT_USER hive are placed into HKEY_USERS\.Default._”

Hopefully now more people will know about this, and you will update your script to accommodate this. :)

Arthur said...

My last comment was incomplete. Here we go again:

Actually, editing HKEY_USERS \.DEFAULT (for example, to change numlock, the wallpaper or default keyboard layout at logon) is possible using .admx files. However, nobody has ever documented this on technet, which is why nobody knows about it Refer this file, the only document currently existing on the internet that actually mentions this being possible:

http://download.microsoft.com/download/8/F/B/8FBD2E85-8852-45EC-8465-92756EBD9365/WindowsServer2008andWindowsVistaSP1GroupPolicySettings.xlsx



I am quoting the specific part from the sheet “AdministrativeTemplate” from cell G385, emphasis mine:

“_Registry policy_ allows an administrator to configure registry settings of any type. /This policy differs significantly from Administrative Templates policy/, which limits registry options and requires templatization of all settings. This policy can be used in conjunction with Security Settings\Registry policy, which allows an administrator to define access permissions and audit settings for registry keys. _/Computer policy/ registry settings that target the HKEY_CURRENT_USER hive are placed into HKEY_USERS\.Default._”

Hopefully now more people will know about this, and you will update your script to accommodate this. :)

marianok said...
This comment has been removed by the author.
marianok said...

Dear Arthur, first of all thanks for looking at my script and for your comment.
Now, regarding hku\.Default:
There is a miss conception about this key.
Many people think that if they want to assign a default (wallpaper, screensaver, etc.) to a user, they can just add it here and this key will copied when the user first logs into the system.
This is incorrect. If you want to do this, you have 2 options: a) you use a regular GPO and set the properties in HKU, OR b) you edit the ntuser.dat for the default user and set there the corresponding setting. The NTUSER.dat for the default user DOES get copied into new users, so it can be used to “seed” default settings.

Some people believe that this key can be used to set default settings for all users (new and existing) this is plain wrong as the correct way to update the properties for existing users is a GPO policy (and set the modifications on the corresponding HKU policy). While updating the NTUSER.DAT for the default user WILL apply the changes to new users (as explained before) this change will not be applied to users that already have a profile on the system.

HKU\.Default is only for the “Local System” Account, so, if you wish, you COULD use this to set the background and the screensaver for the “Local System” Account. That screen saver would be used whenever no user is logged into the system.

You can check http://blogs.msdn.com/b/oldnewthing/archive/2007/03/02/1786493.aspx and (if you have an old copy of TechNet) you can take a look to kb articles 305709 and 291586 where this is briefly mentioned.


Now, if you are asking if it’s possible to have a GPO to update the HKU\.Default subtree, the answer is “YES WE CAN” (sorry for the political joke  I just like Obama)

But this if you are asking if this script will generate an admx capable of updating HKU\.Default subtree, the answer is NO.
Let me explain it:
This script was developed with applications in mind, meaning the fact that we all have some application that our end users run but needs a set of registry values in place.
Most of the time this applications will ship with a sample .reg file and some documentation on the different keys and values, but they will not provide the system administrators with ADMX files to do the centralize management (Microsoft, and Symantec are the only exceptions I can remember).
So I developed this script to grab that sample .reg file and generate a valid .admx policy template.
In this process I made assumptions, one of those assumptions was that the administrators are a lot more likely to care about “real” users than they are about what happens when no one uses the system, so I decided that all HKU\.Default should be treated as a HKU.

If this is what you need, let me know, I can give you a couple changes to do in the script that would accomplish this.

Trentent said...

This registry key breaks the script when you try loading it via GPMC:
Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Windows Messaging Subsystem\Profiles]
"101e6613"=hex:06,00,00,00,1c,00,00,00,30,00,00,00,52,00,00,00,68,00,00,00,7d,\
00,00,00,91,00,00,00,6e,63,61,6c,72,70,63,3a,43,43,53,43,47,59,45,58,43,30,\
31,00,6e,63,61,63,6e,5f,69,70,5f,74,63,70,3a,43,43,53,43,47,59,45,58,43,30,\
31,2e,63,63,73,2e,63,6f,72,70,00,6e,63,61,63,6e,5f,73,70,78,3a,43,43,53,43,\
47,59,45,58,43,30,31,00,6e,63,61,63,6e,5f,6e,70,3a,43,43,53,43,47,59,45,58,\
43,30,31,00,6e,65,74,62,69,6f,73,3a,43,43,53,43,47,59,45,58,43,30,31,00,6e,\

63,61,63,6e,5f,76,6e,73,5f,73,70,70,3a,43,43,53,43,47,59,45,58,43,30,31,00

The error generated is:
[Window Title]
Administrative Templates

[Main Instruction]
Encountered an error while parsing.

[Content]
Expected one of the following possible element(s), , , , , , , , , , but found instead.

File \\lab\SysVol\ccs.corp\Policies\PolicyDefinitions\en-US\WindowsMessagingSubsystem.adml, line 16, column 222

[OK]

marianok said...

Dear Trentent, thanks for looking at my script and for your feedback.
Regarding the error, the source of the problem is that the value that you included is a HEX encoded value, and I had been unable to find documentation on how to define this values on ADMX/L.
(see the caveats section on my original post)

So the script works arround this by defining it as a string, but it is very lieklly that his will not work 100% of the cases.

I'm still trying to get the documentation for this cases, but everytime I contacted Microsoft on this I came up empty handed.

If you (or anyone) can tell me how to code HEX / HEX(0) records on the ADMX/L definition I would be more that glad to program it into this tool.

Best Regards, Marianok

Matt Broadstock said...

First off, fantastic script! Works great and saves a ton of time creating ADMx files.

I have some code that you might find handy. I like to create ADMx files with multiple entries for related purposes and the XML output from this script has the XML all "jumbled" on one line so it is tough to copy/paste into my existing ADMx files. I have a couple of VBS functions that will format the XML on separate lines. It creates a new ADMx file that is formatted. I haven't bothered to do the code to create a copy of the ADMl with the same base file name as the new ADMx but that could easily be added (or, you could possibly replace the original ADMx with the formatted one--I just didn't want to change too much of your code).

I am not sure how the code will look in a comment but here it is:

EDIT: I can't post more than 4096 characters so I cannot include the code. I am more than happy to send it to you if you are interested. Or, I can probably split it up into a few comments...

Thanks again, Matt

marianok said...

Dear Matt, Thanks for your feedback and comments. For sure I'm interested in your code to make the XML look nicer. I looked at doing it myself, but I did not like the work-around involved (either changing the APIs used or reopening the file as text and massaging it that way).

I'm preparing a newer version of the script incorporating some changes suggested by Uwe Riecken in the Technet site, so it might be a great opportunity to add you contribution as well.


please send me your code to: sample at marianok d0t com d0T ar


Thanks again for your feedback, looking forward to hear from you.

ChielV said...

The registry value for default ("@") is set to "(Default)" in the .ADMX file, which does not work.

You can make it work by replacing "(Default)" to an empty string "" in the .ADMX file after running the script and you will get the desired result.