Click to Rate and Give Feedback
Tips
In the unfortunate case that you have to use the REPAIR_ALLOW_DATA_LOSS option, some data will inevitably be lost. Find out how you can determine what data was lost when running the repair option. ...

Read more!

You can't directly update SQL Server 2000 log shipping to SQL Server 2008 log shipping. But you can easily migrate your SQL Server 2000 log shipping configuration to SQL Server 2008. Learn how. ...

Read more!

With the Microsoft Filter Pack, you can extend the Windows Search service to support more file types, including OneNote and Zip files. ...

Read more!

Each mailbox has an Exchange alias and display name associated with it. You can change the Exchange alias in four steps. ...

Read more!

If you want external users or mail systems to be able to send mail to an address within your organization and then have Exchange forward this mail to an external mailbox, we list the six easy steps to get it done. ...

Read more!

Related Articles

Discover how you can use disconnected recordsets—virtual database tables—to work around VBScript limitations relating to data-sorting and working with large data sets.

The Microsoft Scripting Guys

TechNet Magazine September 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!

Learn how you can implement error-handling in Windows PowerShell.

Don Jones

TechNet Magazine January 2009

...

Read more!

With Windows Vista, the UserAccounts.CommonDialog ActiveX control for opening a file open dialog box no longer exists. Here's a look at how you can solve that problem using Visual Basic Express Edition.

The Microsoft Scripting Guys

TechNet Magazine August 2008

...

Read more!

In the past few installments of the Windows PowerShell column, Don Jones has been demonstrating how to develop a Windows PowerShell-based inventory tool. In this installment, Don brings it all together into a very powerful, full-featured tool, and offers some guidance on customizing the tool for your own needs.

Don Jones

TechNet Magazine February 2009

...

Read more!

Also by this Author

With Windows Vista, the UserAccounts.CommonDialog ActiveX control for opening a file open dialog box no longer exists. Here's a look at how you can solve that problem using Visual Basic Express Edition.

The Microsoft Scripting Guys

TechNet Magazine August 2008

...

Read more!

Automating data entry is more important than ever, and today’s automation language is Windows PowerShell. This article uses Windows PowerShell to collect some data about the local computer and write it to an Office Access database.

The Microsoft Scripting Guys

TechNet Magazine May 2009

...

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!

The scripting guys visit the Louvre, take up art criticism, and show you how to use regular expressions in a script to do a search and replace.

The Microsoft Scripting Guys

TechNet Magazine May 2008

...

Read more!

The Scripting Guys demonstrate how you can change the last-modified date of a file with some script and the Shell object.

The Microsoft Scripting Guys

TechNet Magazine March 2008

...

Read more!

Popular Articles

Discover how to use the Excel.Application automation model for a more powerful way to process data from your servers and take advantage of the analysis and charting tools built into Excel.

The Microsoft Scripting Guys

TechNet Magazine January 2009

...

Read more!

Why do attachment sizes increase when sending and receiving e-mail messages? How can you ensure databases on a passive node in a CCR cluster are defragmented during online maintenance? Can you use an external trust between forests? We answer these questions and more.

Henrik Walther

TechNet Magazine January 2009

...

Read more!

Without too much effort, you can deploy a terminal server to host the applications you need in your environment. But there are some important decisions you’ll need to make to ensure your implementation meets user expectations. Greg Shields discusses the various options you have and explains how they will affect you.

Greg Shields

TechNet Magazine January 2009

...

Read more!

Raymond Chen looks at the skewed relationship bugs have to errors, and explains why it's important that programmers suffer as well as give results.

Raymond Chen

TechNet Magazine October 2008

...

Read more!

Learn how you can implement error-handling in Windows PowerShell.

Don Jones

TechNet Magazine January 2009

...

Read more!

Our Blog

NAP monitors the health of specified computers when they attempt to connect to a network and includes a number of mechanisms to enforce health requirements. In this article, Geek of All Trades Greg Shields gives readers an overview of these enforcement mechanisms and, as an example, takes a closer look at setting ...

Read more!

Use Windows PowerShell to Manage Virtual Machines Here are a few examples of how you can use Windows PowerShell scripts to manage virtual machines running on a Server Core installation. Note that these scripts are presented as samples and may need to be customized to work in your environment.

Create a New ...

Read more!

Disabling an Unused Part of Group Policy Objects One way to disable a policy is to disable an unused part of the GPO. By disabling part of a policy that isn’t used, the application of GPOs and security will be faster.

Administer Windows Server 2008 Server Core from the Command Prompt ...

Read more!

In the August 2008 issue of TechNet Magazine, Paul Randal wrote an article Top Tips for Effective Database Maintenance.  It was geared toward "involuntary  DBAs" (IT pros who inadvertently wind up responsible for a SQL Server instance).  The article had a great response from our readers so Paul has written another ...

Read more!

Microsoft Forefront is designed to deliver an integrated security solution that makes it much easier to deploy and manage security across an organization’s IT infrastructure. In this, our annual security issue, we feature two articles that describe how Forefront Security protects instant messaging and e-mail.

Protect ...

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