How to delete a Key and its Subkeys from the Registry.

Can you delete a single registry key using a scriptthe following script:

Const HKEY_CURRENT_USER = &H80000001

strComputer = “.”

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

objReg.DeleteKey HKEY_CURRENT_USER, strKeyPath

The script above removes a registry key; unfortunately, it won’t remove registry keys. Suppose a key has a couple of subkeys underneath it.

The Windows Management Instrumentation (WMI) DeleteKey method can delete a single registry key, but it can’t delete multiple registry keys. If the key to be removed has any subkeys, the script above won’t remove a thing—try it.

To remove registry keys with a script, even registry keys that have subkeys. All you have to do is act recursively.

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
End If

objRegistry.DeleteKey HKEY_CURRENT_USER, strKeyPath
End Sub

Thescript 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.

You then assign the name of the computer (using a dot to represent the local computer) to a variable named strComputer, and assign the path to the registry key you want deleted (Software\Test) to a variable named strKeyPath.

After that 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 you don’t try to delete the registry key at this point. Why not? Well, if this registry key has any subkeys we can’t delete it. Therefore, you need to call a subroutine named DeleteSubkeys, passing as parameters the constant HKEY_CURRENT_USER and the variable strKeyPath.

Once inside the subroutine, the first thing to 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 be seen, three parameters are passed to EnumKey: HKEY_CURRENT_USER, strKeyPath, and an “out” parameter named arrSubkeys. Note that no value was assigned to arrSubkeys. That’s because with an out parameter, all you need to 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 that the Test key has two subkeys: Subkey 1 and Subkey 2.

Suppose either Subkey 1 or Subkey 2 has subkeys of their own. Because it is not possible to delete registry keys that have subkeys, the presence of Subkey A will cause the script to fail.

So what to do now? The first thing is to 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, set up a For Each loop, one that loops through all the subkeys stored in the variable arrSubkeys (which, contains the values Subkey 1 and Subkey 2).

Note that, even though you already in the DeleteSubkeys subroutine, you go ahead and call that subroutine again. (That’s what recursion is all about.) This time you call the subroutine using the current registry path (stored in the variable strKeyPath) plus a \ and the name of the subkey you’re looking at. In other words, the first time through this loop you’ll be looking at the subkey Subkey 1. Therefore, DeleteSubkeys is called 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 you call DeleteSubkeys a third time, this time passing the value Software\Test\Subkey 1\Subkey A.

Subkey A has no subkeys of its own; that means the IsArray function comes back False. That also means that you’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. What has been 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, you go ahead and delete Subkey A.

That’s nice, but it still leaves a bunch of other subkeys to delete (not to mention the Test key that you started with). How to get rid of those other registry keys?

Tis 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.

It is important to get a grasp on how this script works, as 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.

For more information on writing WMI scripts that deal with the registry, take a peek at this chapter in the “Scripting Guide”.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: