Printer Friendly Version      Send     
Click to Rate and Give Feedback
Related Articles
Active Directory, why it rocks! ...

Read more!

This Tip will explain how to send email from Exchange ...

Read more!

New Tip ...

Read more!

You know what ...

Read more!

Also by this Author

The AllSigned execution policy provides the most secure Windows PowerShell environment. So how do you sign your Windows PowerShell scripts? Don Jones shows you how.

The Microsoft Scripting Guys

TechNet Magazine April 2008

...

Read more!

The Scripting Guys discuss adrenaline-filled scripting and show you how the new boot configuration data store in Windows Vista and Windows Server 2008 can be accessed using scripts.

The Microsoft Scripting Guys

TechNet Magazine July 2008

...

Read more!

The Scripting Guys ponder hard work, true happiness, and outputting data to the command window in a readable tabular format.

The Microsoft Scripting Guys

TechNet Magazine June 2008

...

Read more!

This month, The Scripting Guys take a close look at the WMI infrastructure. Along the way, they provide some helpful scripts that can serve as a starting point for learning more and accomplishing useful administrative tasks.

The Microsoft Scripting Guys

TechNet Magazine November 2008

...

Read more!

The Microsoft Scripting Guys go on and on about the 2008 Scripting Games, and they also show you how to create, append, and modify XML documents. By the way, have you heard about the 2008 Scripting Games?

The Microsoft Scripting Guys

TechNet Magazine February 2008

...

Read more!

Popular Articles

Face it, most of the users you support just don't back up there data. SyncToy provides an unintrusive way to ensure your users' files are always backed up and ready to be easily restored.

Jay Munro

TechNet Magazine March 2007

...

Read more!

The latest release of IIS introduces a modular and extensible platform with improved support for common deployment and management scenarios, enabling significant performance improvements. Here’s a look at 10 key areas in IIS 7.0 that provide these improvements.

Mike Volodarsky

TechNet Magazine September 2008

...

Read more!

This month we continue our in-depth discussion about what’s new in the Windows Vista kernel. In this issue, we review some advancements in how Windows Vista manages memory and explore the areas of system startup, shutdown, and power management.

Mark Russinovich

TechNet Magazine March 2007

...

Read more!

User Account Control, or UAC, is one of the most misunderstood new features in Windows Vista. But its goal—to enable users to run with standard user rights—can solve many security issues. Get an inside look at the problems UAC is designed to address and see exactly how this new feature works.

Mark Russinovich

TechNet Magazine June 2007

...

Read more!

See how this free utility can help you determine whether problems you are experiencing while running Windows are caused by faulty memory.

Lance Whitney

TechNet Magazine September 2008

...

Read more!

Our Blog

Want to be proactive about preventing data loss? Enterprise rights management is the way to go. Discover how   the Microsoft Enterprise Rights Management solution can protect your organization's information from unauthorized access and use.

Read more!

Windows Management Instrumentation (WMI) is the Microsoft implementation of Web-based Enterprise Management (WBEM)—a technology that lets you access information about the objects in your enterprise environment that have to be managed, such as systems, applications, networks, devices, and other managed components. Not surprisingly, the information is accessible via script ...

Read more!

In every issue of TechNet Magazine, Greg Steen (a practicing IT professional) discusses free and relatively inexpensive tools and utilities that help him do his IT work and "getting the job done." 

In the November issue, Greg looks at mapping data graphically with MapForce, creating and managing ...

Read more!

The latest installment of our online-only Sustainable Computing column is now available.

Find out how you can:

Bring Windows Server 2008 and Windows Vista Power Management Settings into Compliance Bring Windows Server 2003 and Windows XP Power Management Settings into Compliance Enforce Energy-Efficient Architectures ...

Read more!

Last year around this time, TechNet Magazine featured an article about the Microsoft Security Intelligence Report - a comprehensive study by the Microsft Malware Protection Center of the computer security landscape. Well, the latest SIR (volume 5) has just been released, and it's packed with a detailed analysis of current threats, as well as updates on available countermeasures. Head ...

Read more!

Hey, Scripting Guy! How Can I Delete a Key and its Subkeys from the Registry?
The Microsoft Scripting Guys

Download the code for this article: ScriptingGuys2006_08.exe (150KB)

A few years ago, Aaron, a neighbor kid who lived a couple of houses away, would come by every day to play with one of the Scripting Sons (come to think of it, the only Scripting Son). Aaron was a nice enough kid, but he had one very annoying habit: he was always munching away on treats. The treats themselves weren’t a problem, but whatever he was eating—Popsicles, Hostess cupcakes, or what-have-you—Aaron would simply drop his wrappers where he stood, which was invariably in the Scripting Guy’s yard. At first the Scripting Guy simply picked up the wrappers and threw them away. As time went on, however, and as the wrappers started to pile up, the Scripting Guy suggested to Aaron that maybe he ought to throw his wrappers in the garbage can. As time continued to go on, these suggestions became a bit stronger. Eventually the Scripting Guy reached the breaking point. "Aaron," he said, "I’m tired of picking up your garbage every single day. From now on you are banished from our yard. Scripting Son can go over to your house to play, but you are not allowed to set foot in our yard. Ever."
The next day, when the Scripting Guy arrived home from work, he found Aaron standing in the yard, eating a Popsicle. "Hey, Aaron," said the Scripting Guy, "didn’t I tell you yesterday that you were never allowed to come in our yard again?"
Aaron was nonplussed by such a silly question. "Yes," he said, and he went back to eating his Popsicle.
If you’re on the edge of your seat, dying to know how the Scripting Guy reacted, you might be disappointed: he simply stood there for a moment and then walked into the house without saying a word. It wasn’t that the Scripting Guy wasn’t upset, it’s just that he had had a sudden epiphany: there are some things in this world that you simply can’t get rid of—Aaron was one of those things. The Scripting Guy might have considered himself an irresistible force, but he suddenly realized that, like dandelions and registry keys, Aaron (and his Popsicle wrappers) was an unremovable object.
And yes, you read that correctly: in addition to Aaron and his Popsicle wrappers, two other things you can’t get rid of are dandelions and registry keys. We know what you’re thinking: "OK, dandelions I agree with; after all, one of the Scripting Guys once found a dandelion growing in a storage room in which his son had tossed his muddy shoes. But registry keys? Registry keys are easy to get rid of; heck I can even write a script that deletes registry keys."
To tell you the truth, you’re right—sort of. Suppose you have a single registry key in the registry, something along the lines of Figure 1.
Figure 1 Dandelion? No, Registry Key 
Can you delete this single registry key using a script? You bet you can; in fact, this script right here will do that for you:
Const HKEY_CURRENT_USER = &H80000001

strComputer = "."

Set objReg = GetObject("winmgmts:\\" & _
    strComputer & "\root\default:StdRegProv")
strKeyPath = "SOFTWARE\Test"

objReg.DeleteKey HKEY_CURRENT_USER, strKeyPath
"Wait a second," you say. "First you tell us that registry keys are unremovable, then you show us a script that removes registry keys. What’s the deal here?"
Well, the deal is that we showed you a script that removes a registry key; unfortunately, it won’t remove registry keys. Suppose the Test key has a couple of subkeys underneath it, as in Figure 2.
That’s a problem. The Windows Management Instrumentation (WMI) DeleteKey method can delete a single registry key, but it can’t delete multiple registry keys. If the Test key has any subkeys, the script we just showed you won’t remove a thing—try it and you’ll see what we mean.
Figure 2 Ah, They Multiply 
You might not realize it, but we’re in a spot of trouble here—after all, we can’t delete the Test key without deleting Subkey 1 and Subkey 2. Even worse, we can’t delete Subkey 1 until we first delete Subkey A. And if Subkey A happens to have any subkeys, well.... Is this one of those situations where we have to just walk quietly into the house, recognizing that some things can’t be removed?
Fortunately, no. Our Scripting Guy never did figure out what to do about Aaron (other than hope that he’d eventually grow up and move away). As it turns out, though, it is possible to remove registry keys with a script, even registry keys that have subkeys. All you have to do is act recursively.
We don’t have time to explain recursion in detail today; for more information you might want to take a look at the "Microsoft Windows 2000 Scripting Guide". For now we’ll just note that a recursive subroutine is simply a subroutine that can call itself. How does that help us? Take a look at the accompanying script and then we’ll try to explain how it all works.
On Error Resume Next 

Const HKEY_CURRENT_USER = &H80000001 

strComputer = "."
strKeyPath = "Software\Test" 

Set objRegistry = GetObject("winmgmts:\\" & _
    strComputer & "\root\default:StdRegProv") 

DeleteSubkeys HKEY_CURRENT_USER, strKeypath 

Sub DeleteSubkeys(HKEY_CURRENT_USER, strKeyPath) 
    objRegistry.EnumKey HKEY_CURRENT_USER, strKeyPath, arrSubkeys 

    If IsArray(arrSubkeys) Then 
        For Each strSubkey In arrSubkeys 
            DeleteSubkeys HKEY_CURRENT_USER, strKeyPath & "\" & strSubkey 
        Next 
    End If 

    objRegistry.DeleteKey HKEY_CURRENT_USER, strKeyPath 
End Sub

Our script starts off simply enough, defining a constant named HKEY_CURRENT_USER and setting the value to &H80000001. This tells the script which registry hive to work with. For more information on writing WMI scripts that deal with the registry, take a peek at this chapter in the "Scripting Guide".
We then assign the name of the computer (using a dot to represent the local computer) to a variable named strComputer, and we assign the path to the registry key we want deleted (Software\Test) to a variable named strKeyPath.
After that we connect to the WMI service, taking care to bind to the root\default namespace. (Although you typically find WMI classes in root\cimv2, you won’t find the System Registry provider there.)
Now it gets interesting. Notice that we don’t try to delete the registry key at this point. Why not? Well, as we’ve already learned, if this registry key has any subkeys we can’t delete it. Therefore, we call a subroutine named DeleteSubkeys, passing as parameters the constant HKEY_CURRENT_USER and the variable strKeyPath.
Once we’re inside the subroutine, we delete the registry key, right? Nope, sorry; remember that operation will fail if the key has any subkeys. Instead, the first thing we do is call the EnumKey method, a method that returns a list of all the subkeys (if any) found in the registry key Test. As you can see, we pass EnumKey three parameters: HKEY_CURRENT_USER, strKeyPath, and an "out" parameter named arrSubkeys. If you’re thinking, "Hey, we didn’t even assign a value to arrSubkeys," well, you’re right, we didn’t. That’s because with an out parameter, all we do is supply a variable name and the method assigns it a value. In this case, that value will be a list of all the subkeys found in Test.
EnumKey will end up telling us that the Test key has two subkeys: Subkey 1 and Subkey 2. And, no, we still can’t start deleting registry keys. Why not? Well, suppose either Subkey 1 or Subkey 2 has subkeys of their own. (And one of them does: Subkey 1 has a subkey named Subkey A.) Because we can’t delete registry keys that have subkeys, the presence of Subkey A will cause the script to fail. (And, yes, everything seems to cause this script to fail doesn’t it? But don’t lose hope.)
So what do we do now? Well, brace yourself, because this is where it really gets confusing. The first thing we do is use the IsArray function to determine whether the variable arrSubkeys is an array. If it is, the Test key does have at least one subkey (otherwise arrSubkeys would have no value at all). Because IsArray comes back True, we set up a For Each loop, one that loops through all the subkeys stored in the variable arrSubkeys (which, just to remind you, contains the values Subkey 1 and Subkey 2).
Note that, even though we’re already in the DeleteSubkeys subroutine, we go ahead and call that subroutine again. (That’s what recursion is all about.) This time we call the subroutine using the current registry path (stored in the variable strKeyPath) plus a \ and the name of the subkey we’re looking at. In other words, the first time through this loop we’ll be looking at the subkey Subkey 1. Therefore, we call DeleteSubkeys a second time using strKeyPath (Software\Test) plus \Subkey 1; in other words, Software\Test\Subkey 1. As you know, this happens to be the path to the first subkey found in the Test key.
So now what happens? Well, the DeleteSubkeys subroutine will call the EnumKey method to determine whether Subkey 1 has any subkeys of its own. As it turns out, it does. Because of that we call DeleteSubkeys a third time, this time passing the value Software\Test\Subkey 1\Subkey A.
We told you it would get confusing.
Fortunately (for the sake of our sanity), Subkey A has no subkeys of its own; that means the IsArray function comes back False. That also means that we’ll be able to skip the line of code that calls the DeleteSubkeys subroutine and, instead, call objRegistry.DeleteKey to delete Subkey A—and only Subkey A. Still with us? What we’ve done so far is follow the path down to Software\Test\Subkey 1\Subkey A and finally found a registry key with no subkeys. Because of that, we go ahead and delete Subkey A.
Good point. That’s nice, but it still leaves us with a bunch of other subkeys to delete (not to mention the Test key that we started with). How the heck do we get rid of those other registry keys?
To be honest, this is where it helps to have a little blind faith in VBScript. Each time VBScript calls the recursive subroutine, it makes a note to itself as to what’s going on. In other words, when DeleteSubkeys checks the subkey Software\Test\Subkey 1\Subkey A VBScript is well aware that the other keys exist, too.
After deleting Subkey A, VBScript automatically goes back to Subkey 1 to see if it has any other subkeys. Because it doesn’t, the script then deletes Subkey 1. The script then runs this check on Subkey 2, the other subkey found in Test. Because Subkey 2 has no subkeys, it gets deleted as well. (This will continue based on how many subkeys and sub-subkeys you might have.)
After deleting Subkey 2 VBScript goes back and checks the Test key. Because this key no longer has any subkeys, Test gets deleted, and our work is done. Try it and see.
If you feel like your head is about to explode, don’t worry (well, not unless your head actually does explode). If you’d rather not delve into the intricacies of recursion, then just use the script as is and don’t give it a second thought. Of course, having said that we recommend that you try walking through this scenario a few times until it begins to make sense. Why? Well, if you ever can get a grasp on how this script works then you’ll be able to write recursive scripts of your own. And that means being able to write scripts that, for example, enumerate all the values in all the subkeys of a registry key or list all the files in all the subfolders of a folder.
The main thing is that this scenario has a happy ending: we figured out a way to remove hitherto unremovable registry keys. That doesn’t mean this approach will work for everything: dandelions, to name one, seem immune to recursive subroutines. As for Aaron, well, as he and the Scripting Son grew older their interests began to diverge, and the two don’t spend much time together anymore. Nevertheless, the other day, when our Scripting Guy returned home, he found an empty Big Gulp cup lying in the front yard. Like we said, there are some things you just can’t get rid of.
A Note from the Scripting Guys
Weekly Scripting Puzzle
Everyone knows that if you don’t use a skill regularly you become, well, a little less skilled. (How many of us really remember our high school algebra?) Don’t let that happen to your scripting skills. The Scripting Puzzle is a fun way to hone your skills. You’ll find a new puzzle on the Script Center every Friday.

Scripting Newswire
Be the first in your neighborhood to get the scoop on everything going on in the Script Center. Or if it’s too late to be the first, don’t be left out—the peer pressure is getting to you isn’t it? Sign up now for the Scripting Newswire, delivered directly to you inbox every month. Send e-mail to scripter@microsoft.com with the subject line "Subscribe" and you’ll start receiving your newsletters in no time.


The Microsoft Scripting Guys work for—well, are employed by—Microsoft. When not playing/coaching/watching baseball (and various other activities) they run the TechNet Script Center. Check it out at www.scriptingguys.com.
© 2008 Microsoft Corporation and CMP Media, LLC. All rights reserved; reproduction in part or in whole without permission is prohibited.
Page view tracker